這篇文章主要為大家展示了“C#中Entity Framework常見報錯有哪些”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“C#中Entity Framework常見報錯有哪些”這篇文章吧。
創(chuàng)新互聯(lián)公司專注于綿陽網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供綿陽營銷型網(wǎng)站建設(shè),綿陽網(wǎng)站制作、綿陽網(wǎng)頁設(shè)計、綿陽網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務(wù),打造綿陽網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供綿陽網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
1 實體屬性配置為IsRequired()對更新的影響
拋出異常類型DbEntityValidationException
表結(jié)構(gòu):
實體:
public class User { public int Id { get; set; } ////// 賬號 /// public string Account { get; set; } ////// 郵箱 /// public string Email { get; set; } ////// 昵稱 /// public string Nickname { get; set; } ////// 頭像 /// public string AvatarId { get; set; } ////// 記錄插入時間 /// public DateTime InsertTime { get; set; } ////// 記錄修改時間 /// public DateTime UpdateTime { get; set; } }
實體配置:
modelBuilder.Entity().Property(u => u.Account) .IsRequired() .IsUnicode(false) .HasMaxLength(50); modelBuilder.Entity ().Property(u => u.Email) .IsRequired() .IsUnicode(false) .HasMaxLength(100); modelBuilder.Entity ().Property(u => u.Nickname) .IsUnicode(false) .HasMaxLength(50); modelBuilder.Entity ().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() Database.SetInitializer (null); } public DbSet 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", }; DbEntityEntryentry = db.Entry (user); entry.State = EntityState.Unchanged; entry.Property(t => t.Email).IsModified = true; int num = db.SaveChanges(); }
執(zhí)行操作,報錯信息如下:
查看EntityValidationErrors,
只能看到{System.Data.Entity.Validation.DbEntityValidationResult},沒有更詳細的信息。
如果將上述代碼用try..catch包起來,如下寫法:
try { //執(zhí)行代碼 } catch (DbEntityValidationException ex) { var e = ex.EntityValidationErrors; } catch (Exception ex) { }
一層一層地打開,看到真正導(dǎo)致異常的原因,看到下面的截圖:
分析實體配置發(fā)現(xiàn),Account屬性被設(shè)置為IsRequired,那么在更新實體的時候,即使不更新這個字段,也要給這個字段賦值,那么賦值后觀察:
更新操作代碼變?yōu)?/p>
using (CustomDbContext db = new CustomDbContext()) { User user = new User { Id = 1, Email = "test@1622.com", Account = "a" }; DbEntityEntryentry = db.Entry (user); entry.State = EntityState.Unchanged; entry.Property(t => t.Email).IsModified = true; int num = db.SaveChanges(); }
經(jīng)過上述調(diào)整后,更新成功。
那么換一個思路,將Account屬性被設(shè)置為IsOptional()是不是也可以呢?
修改實體配置,將Account屬性設(shè)置按如下修改,并注掉上面的Account = "a"
modelBuilder.Entity
.IsOptional()
.IsUnicode(false)
.HasMaxLength(50);
執(zhí)行測試,更改成功。
得出結(jié)論:在實體配置時,指定了為必選的字段,那么更新操作時,構(gòu)造實例一定要對必選(IsRequired())字段賦值。
上述測試中還有一個值得考慮的細節(jié),構(gòu)造User實例的時候,只對Id,Email進行了賦值,而沒有對其他屬性進行賦值,那么為什么會成功呢?那么必定是未進行任何設(shè)置的實體屬性默認是IsOptional()。這跟表結(jié)構(gòu)中的字段類型設(shè)置為Not Null有無關(guān)聯(lián)呢,從測試結(jié)果看就本類應(yīng)用無必然聯(lián)系。
總結(jié):
a.實體配置中指定了實體屬性為IsRequired(),更新操作構(gòu)造類的實例時必對此屬性賦值。
b.不進行配置的實體屬性默認為IsOptional()
c.表結(jié)構(gòu)中字段是否為Not Null對上述規(guī)則無影響。
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
實體屬性配置如上例所示。
操作代碼:
using (CustomDbContext db = new CustomDbContext()) { User user = new User { Id = 1, Email = "test@132.com", }; DbEntityEntryentry = db.Entry (user); entry.State = EntityState.Unchanged; entry.Property(t => t.Email).IsModified = true; User user1 = new User { Id = 1, Email = "test@132.com", }; DbEntityEntry entry1 = db.Entry (user1); entry1.State = EntityState.Unchanged; entry1.Property(t => t.Email).IsModified = true; int num = db.SaveChanges(); }
執(zhí)行操作
涉及到兩次修改操作,兩次操作構(gòu)造了兩個實例,但是實例的屬性Id有相同的值。
如果兩次操作的是同一個實例,而不是不同的實例,那么不會拋出異常,代碼如下:
using (CustomDbContext db = new CustomDbContext()) { User user = new User { Id = 1, Email = "test@132.com", }; DbEntityEntryentry = db.Entry (user); entry.State = EntityState.Unchanged; entry.Property(t => t.Email).IsModified = true; DbEntityEntry entry1 = db.Entry (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是主鍵:
using (CustomDbContext db = new CustomDbContext()) { User user = new User { //Id = 1, Email = "test@132.com", }; DbEntityEntryentry = db.Entry (user); entry.State = EntityState.Unchanged; entry.Property(t => t.Email).IsModified = true; int num = db.SaveChanges(); }
運行上述代碼,拋出異常信息如下,注意異常類型居然是System.Data.Entity.Infrastructure.DbUpdateConcurrencyException,看上去像是并發(fā)問題,但實際卻不是!
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.
賦給主鍵一個不存在的值,令I(lǐng)d=4(在數(shù)據(jù)庫表中不存在Id為4的一條記錄)拋出的異常與上面的相同。
4 字段超長拋出異常:System.Data.Entity.Validation.DbEntityValidationException
表中Nickname 字段定義為50個字符,現(xiàn)在賦值超過50。
操作代碼如下:
using (CustomDbContext db = new CustomDbContext()) { User user = new User { Id = 4, Email = "test@132.com", Nickname = "TestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateErrorTestUpdateError" }; DbEntityEntryentry = db.Entry (user); entry.State = EntityState.Unchanged; entry.Property(t => t.Email).IsModified = true; int num = db.SaveChanges(); }
運行程序報錯:
一層一層點開,查看具體原因:
以上是“C#中Entity Framework常見報錯有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!