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

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值