MVC中EF中解决模型类NotMapped属性无效,即列名"xx"无效

来源:互联网 发布:高端人群社交软件 编辑:程序博客网 时间:2024/06/02 03:43

1.首先我们当看异常堆栈信息

  System.Data.EntityCommandExecutionException: 执行命令定义时出错。有关详细信息,请参阅内部异常。 ---> System.Data.SqlClient.SqlException: 列名 'NewPassword' 无效。   在 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)   在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)   在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)   在 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)   在 System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()   在 System.Data.SqlClient.SqlDataReader.get_MetaData()   在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)   在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest)   在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)   在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)   在 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)   在 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)   在 System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)   在 System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)   --- 内部异常堆栈跟踪的结尾 ---   在 System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)   在 System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)   在 System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)   在 System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()   在 System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)   在 System.Data.Objects.ELinq.ObjectQueryProvider.<>c__11`1.<GetElementFunction>b__11_1(IEnumerable`1 sequence)   在 System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)   在 System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)   在 System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)   在 System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)   在 GMS.Account.BLL.AccountService.Login(String loginName, String password) 位置 C:\GMS1\Src\GMS.Account.BLL\AccountService.cs:行号 59   在 Castle.Proxies.Invocations.IAccountService_Login.InvokeMethodOnTarget()   在 Castle.DynamicProxy.AbstractInvocation.Proceed()   在 GMS.Core.Service.InvokeInterceptor.Intercept(IInvocation invocation) 位置 C:\GMS1\Src\GMS.Core.Service\ServiceHelper.cs:行号 45

2、通过以上堆栈信息可以知道,是因为列名"NewPassword"无效引起的,这时,可以查看模型类,本例中的模型类如下:

[Auditable]    [Table("User")]    public partial class User : ModelBase    {        public User()        {            Roles = new List<Role>();            IsActive = true;            RoleIds = new List<int>();        }        /// <summary>        /// 登录名        /// </summary>        [Required(ErrorMessage = "登录名不能为空")]                public string LoginName { get; set; }        /// <summary>        /// 密码,使用MD5加密        /// </summary>        [Required]        public string Password { get; set; }        /// <summary>        /// 手机号        /// </summary>        [RegularExpression(@"^[1-9]{1}\d{10}$", ErrorMessage = "不是有效的手机号码")]        public string Mobile { get; set; }        /// <summary>        /// 邮箱        /// </summary>        [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}", ErrorMessage = "电子邮件地址无效")]        public string Email { get; set; }        public bool IsActive { get; set; }        /// <summary>        /// 角色列表        /// </summary>        public virtual List<Role> Roles { get; set; }        [NotMapped]        public List<int> RoleIds { get; set; }        [NotMapped]        public string NewPassword { get; set; }        [NotMapped]        public List<EnumBusinessPermission> BusinessPermissionList        {            get            {                var permissions = new List<EnumBusinessPermission>();                foreach (var role in Roles)                {                    permissions.AddRange(role.BusinessPermissionList);                }                return permissions.Distinct().ToList();            }        }    }


3、我们可以看到NewPassword属性已经添加了NotMapped,这时,我们可以调试跟踪,查看SQL语句

SELECT [Extent1].[ID] AS [ID], [Extent1].[LoginName] AS [LoginName], [Extent1].[Password] AS [Password], [Extent1].[Mobile] AS [Mobile], [Extent1].[Email] AS [Email], [Extent1].[IsActive] AS [IsActive], [Extent1].[NewPassword] AS [NewPassword], [Extent1].[CreateTime] AS [CreateTime]FROM [dbo].[User] AS [Extent1]

4、注意上面的SQL语句确实多了列名"NewPassword",那我们查看数据库表,看看表中是否存在此列名


 

5、从上面的截图可以看到,表中确实不存在列名"NewPassword",这时我们可以确定在模型User中的添加的属性"NotMapped"没有起作用,下面就是我的解决方案,

找到DbContext类的派生类,引案例的派生类为DbContextBase,从此派生类中我们双派生另一个类,此类如下:

public class AccountDbContext : DbContextBase    {        public AccountDbContext()            : base(CachedConfigContext.Current.DaoConfig.Account, new LogDbContext())        {        }        protected override void OnModelCreating(DbModelBuilder modelBuilder)        {            Database.SetInitializer<AccountDbContext>(null);            modelBuilder.Entity<User>()                .HasMany(e => e.Roles)                .WithMany(e => e.Users)                .Map(m =>                {                    m.ToTable("UserRole");                    m.MapLeftKey("UserID");                    m.MapRightKey("RoleID");                });            base.OnModelCreating(modelBuilder);            modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();            modelBuilder.Entity<User>().Ignore(u => u.NewPassword);        }        public DbSet<LoginInfo> LoginInfos { get; set; }        public DbSet<User> Users { get; set; }        public DbSet<Role> Roles { get; set; }        public DbSet<VerifyCode> VerifyCodes { get; set; }    }

6、说明一下,上面类中继承关系是AccountDbContext继承DbContextBase,DbContextBase继承DbContext,在重写方法OnModelCreating中添加方法

modelBuilder.Entity<User>().Ignore(u => u.NewPassword);

这样,就解决了NotMapped无效的问题,即异常列名"NewPassword"无效的问题
 

0 0