源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

C#中Entity Framework常见报错汇总

  • 时间:2022-07-08 16:54 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:C#中Entity Framework常见报错汇总
以下小编整理的Entity Framework常见错误的汇总,大家如果还有不明白可以在下面留言区讨论。 [b]1 实体属性配置为IsRequired()对更新的影响[/b] 抛出异常类型DbEntityValidationException 表结构: [img]http://files.jb51.net/file_images/article/201711/2017112616524492.png[/img] 实体:
public class User
  {
    public int Id { get; set; }
    /// <summary>
    /// 账号
    /// </summary>
    public string Account { get; set; }
    /// <summary>
    /// 邮箱
    /// </summary>
    public string Email { get; set; }
    /// <summary>
    /// 昵称
    /// </summary>
    public string Nickname { get; set; }
    /// <summary>
    /// 头像
    /// </summary>
    public string AvatarId { get; set; }
    /// <summary>
    /// 记录插入时间
    /// </summary>
    public DateTime InsertTime { get; set; }
    /// <summary>
    /// 记录修改时间
    /// </summary>
    public DateTime UpdateTime { get; set; }
  }
实体配置:
       modelBuilder.Entity<User>().Property(u => u.Account)
        .IsRequired()
        .IsUnicode(false)
        .HasMaxLength(50);
      modelBuilder.Entity<User>().Property(u => u.Email)
        .IsRequired()
        .IsUnicode(false)
        .HasMaxLength(100);
      modelBuilder.Entity<User>().Property(u => u.Nickname)
        .IsUnicode(false)
        .HasMaxLength(50);
      modelBuilder.Entity<User>().Property(u => u.AvatarId)
        .IsOptional()
        .HasMaxLength(100);
CustomDbContext继承自DbContext
[DbConfigurationType(typeof(MySqlEFConfiguration))]
  public class CustomDbContext : DbContext
  {
    public CustomDbContext()
      : base("name=Master")
    {
      
      this.Configuration.LazyLoadingEnabled = false; 
      //DropCreateDatabaseIfModelChanges
      //new DropCreateDatabaseAlways<CustomDbContext>()
      Database.SetInitializer<CustomDbContext>(null);
    }

    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
      base.OnModelCreating(modelBuilder);
      EntityConfiguration.Set(modelBuilder);
    }
}
更新操作:
using (CustomDbContext db = new CustomDbContext())
{
          User user = new User 
          {
            Id = 1,
            Email = "test@1622.com",
          };
          DbEntityEntry<User> entry = db.Entry<User>(user);
          entry.State = EntityState.Unchanged;
          entry.Property(t => t.Email).IsModified = true;

          int num = db.SaveChanges();
}
执行操作,报错信息如下: [img]http://files.jb51.net/file_images/article/201711/2017112616524493.png[/img] 查看EntityValidationErrors, 只能看到{System.Data.Entity.Validation.DbEntityValidationResult},没有更详细的信息。 如果将上述代码用try..catch包起来,如下写法:
try
{
//执行代码
}
catch (DbEntityValidationException ex)
{
  var e = ex.EntityValidationErrors;
}
catch (Exception ex)
{
}
一层一层地打开,看到真正导致异常的原因,看到下面的截图: [img]http://files.jb51.net/file_images/article/201711/2017112616524494.png[/img] 分析实体配置发现,Account属性被设置为IsRequired,那么在更新实体的时候,即使不更新这个字段,也要给这个字段赋值,那么赋值后观察: 更新操作代码变为  
        using (CustomDbContext db = new CustomDbContext())
        {
          User user = new User 
          {
            Id = 1,
            Email = "test@1622.com",
            Account = "a"
          };
          DbEntityEntry<User> entry = db.Entry<User>(user);
          entry.State = EntityState.Unchanged;
          entry.Property(t => t.Email).IsModified = true;

          int num = db.SaveChanges();
        }    
经过上述调整后,更新成功。 那么换一个思路,将Account属性被设置为IsOptional()是不是也可以呢? 修改实体配置,将Account属性设置按如下修改,并注掉上面的Account = "a" modelBuilder.Entity<User>().Property(u => u.Account)                 .IsOptional()                 .IsUnicode(false)                 .HasMaxLength(50); 执行测试,更改成功。   得出结论:在实体配置时,指定了为必选的字段,那么更新操作时,构造实例一定要对必选(IsRequired())字段赋值。 上述测试中还有一个值得考虑的细节,构造User实例的时候,只对Id,Email进行了赋值,而没有对其他属性进行赋值,那么为什么会成功呢?那么必定是未进行任何设置的实体属性默认是IsOptional()。这跟表结构中的字段类型设置为Not Null有无关联呢,从测试结果看就本类应用无必然联系。 总结: a.实体配置中指定了实体属性为IsRequired(),更新操作构造类的实例时必对此属性赋值。 b.不进行配置的实体属性默认为IsOptional() c.表结构中字段是否为Not Null对上述规则无影响。 [b]2 更新报错:[/b] An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key. 异常类型:System.Data.Entity.Infrastructure.DbUpdateConcurrencyException 实体属性配置如上例所示。 操作代码:
        using (CustomDbContext db = new CustomDbContext())
        {
          User user = new User 
          {
            Id = 1,
            Email = "test@132.com",
          };
          DbEntityEntry<User> entry = db.Entry<User>(user);
          entry.State = EntityState.Unchanged;
          entry.Property(t => t.Email).IsModified = true;

          User user1 = new User
          {
            Id = 1,
            Email = "test@132.com",
          };
          DbEntityEntry<User> entry1 = db.Entry<User>(user1);
          entry1.State = EntityState.Unchanged;
          entry1.Property(t => t.Email).IsModified = true;

          int num = db.SaveChanges();
        }  
执行操作 [img]http://files.jb51.net/file_images/article/201711/2017112616524495.png[/img] 涉及到两次修改操作,两次操作构造了两个实例,但是实例的属性Id有相同的值。 如果两次操作的是同一个实例,而不是不同的实例,那么不会抛出异常,代码如下:
        using (CustomDbContext db = new CustomDbContext())
        {
          User user = new User 
          {
            Id = 1,
            Email = "test@132.com",
          };
          DbEntityEntry<User> entry = db.Entry<User>(user);
          entry.State = EntityState.Unchanged;
          entry.Property(t => t.Email).IsModified = true;

          DbEntityEntry<User> entry1 = db.Entry<User>(user);
          entry1.State = EntityState.Unchanged;
          entry1.Property(t => t.Email).IsModified = true;

          int num = db.SaveChanges();
        }
  [b]3 未给主键赋值或赋给主键一个不存在的值,抛出异常[/b] System.Data.Entity.Infrastructure.DbUpdateConcurrencyException 操作代码如下,其中Id=1这条语句被注掉,Id是主键:
      using (CustomDbContext db = new CustomDbContext())
        {
          User user = new User 
          {
            //Id = 1,
            Email = "test@132.com",
          };
          DbEntityEntry<User> entry = db.Entry<User>(user);
          entry.State = EntityState.Unchanged;
          entry.Property(t => t.Email).IsModified = true;
          int num = db.SaveChanges();
        }  
运行上述代码,抛出异常信息如下,注意异常类型居然是System.Data.Entity.Infrastructure.DbUpdateConcurrencyException,看上去像是并发问题,但实际却不是! Message: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries. [img]http://files.jb51.net/file_images/article/201711/2017112616524496.png[/img] 赋给主键一个不存在的值,令Id=4(在数据库表中不存在Id为4的一条记录)抛出的异常与上面的相同。 [b]4 字段超长抛出异常:System.Data.Entity.Validation.DbEntityValidationException[/b] 表中Nickname 字段定义为50个字符,现在赋值超过50。 操作代码如下:
using (CustomDbContext db = new CustomDbContext())
        {
          User user = new User
          {
            Id = 4,
            Email = "test@132.com",
            Nickname = "TestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateError"
          };
          DbEntityEntry<User> entry = db.Entry<User>(user);
          entry.State = EntityState.Unchanged;
          entry.Property(t => t.Email).IsModified = true;
          int num = db.SaveChanges();
        }
运行程序报错:[img]http://files.jb51.net/file_images/article/201711/2017112616524497.png[/img] 一层一层点开,查看具体原因:[img]http://files.jb51.net/file_images/article/201711/2017112616524498.png[/img]
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部