page contents

C#中Entity Framework常见报错汇总

本文讲述了C#中Entity Framework常见报错汇总!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2022-05-i8STlAqJ6279bcdc3ddd4.png

本文讲述了C#中Entity Framework常见报错汇总!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

1 实体属性配置为IsRequired()对更新的影响

抛出异常类型DbEntityValidationException

表结构:

实体:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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; }
  }

实体配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[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);
    }
}

更新操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
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();
}

执行操作,报错信息如下:

attachments-2022-05-ItMdc1X06279bd6973c83.png

查看EntityValidationErrors,

只能看到{System.Data.Entity.Validation.DbEntityValidationResult},没有更详细的信息。

如果将上述代码用try..catch包起来,如下写法:

1
2
3
4
5
6
7
8
9
10
11
try
{
//执行代码
}
catch (DbEntityValidationException ex)
{
  var e = ex.EntityValidationErrors;
}
catch (Exception ex)
{
}

一层一层地打开,看到真正导致异常的原因,看到下面的截图:

attachments-2022-05-ljMqPnM06279bd745f8c1.png

分析实体配置发现,Account属性被设置为IsRequired,那么在更新实体的时候,即使不更新这个字段,也要给这个字段赋值,那么赋值后观察:

更新操作代码变为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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对上述规则无影响。

2 更新报错:

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

实体属性配置如上例所示。

操作代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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();
}

执行操作

attachments-2022-05-0lSdmHYI6279bd87b7bce.png

涉及到两次修改操作,两次操作构造了两个实例,但是实例的属性Id有相同的值。

如果两次操作的是同一个实例,而不是不同的实例,那么不会抛出异常,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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();
}

3 未给主键赋值或赋给主键一个不存在的值,抛出异常

System.Data.Entity.Infrastructure.DbUpdateConcurrencyException

操作代码如下,其中Id=1这条语句被注掉,Id是主键:

1
2
3
4
5
6
7
8
9
10
11
12
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.

attachments-2022-05-Lu3FBeyO6279bd9a563b6.png

赋给主键一个不存在的值,令Id=4(在数据库表中不存在Id为4的一条记录)抛出的异常与上面的相同。

4 字段超长抛出异常:System.Data.Entity.Validation.DbEntityValidationException

表中Nickname 字段定义为50个字符,现在赋值超过50。

操作代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
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();
        }

运行程序报错:

attachments-2022-05-zQIrx6eI6279bda87e62c.png

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

如果你想用Python开辟副业赚钱,但不熟悉爬虫与反爬虫技术,没有接单途径,也缺乏兼职经验
关注下方微信公众号:Python编程学习圈,获取价值999元全套Python入门到进阶的学习资料以及教程,还有Python技术交流群一起交流学习哦。

attachments-2022-06-t0r4I6zl62b3e14bc8575.jpeg

  • 发表于 2022-05-10 09:16
  • 阅读 ( 415 )
  • 分类:C/C++开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1312 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章