以下小編整理的entity framework常見錯(cuò)誤的匯總,大家如果還有不明白可以在下面留言區(qū)討論。
1 實(shí)體屬性配置為isrequired()對更新的影響
拋出異常類型dbentityvalidationexception
表結(jié)構(gòu):
實(shí)體:
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 > /// 記錄插入時(shí)間 /// </ summary > public datetime inserttime { get; set; } /// < summary > /// 記錄修改時(shí)間 /// </ summary > public datetime updatetime { get; set; } } |
實(shí)體配置:
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(); } |
執(zhí)行操作,報(bào)錯(cuò)信息如下:
查看entityvalidationerrors,
只能看到{system.data.entity.validation.dbentityvalidationresult},沒有更詳細(xì)的信息。
如果將上述代碼用try..catch包起來,如下寫法:
1
2
3
4
5
6
7
8
9
10
11
|
try { //執(zhí)行代碼 } catch (dbentityvalidationexception ex) { var e = ex.entityvalidationerrors; } catch (exception ex) { } |
一層一層地打開,看到真正導(dǎo)致異常的原因,看到下面的截圖:
分析實(shí)體配置發(fā)現(xiàn),account屬性被設(shè)置為isrequired,那么在更新實(shí)體的時(shí)候,即使不更新這個(gè)字段,也要給這個(gè)字段賦值,那么賦值后觀察:
更新操作代碼變?yōu)?/p>
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(); } |
經(jīng)過上述調(diào)整后,更新成功。
那么換一個(gè)思路,將account屬性被設(shè)置為isoptional()是不是也可以呢?
修改實(shí)體配置,將account屬性設(shè)置按如下修改,并注掉上面的account = "a"
modelbuilder.entity<user>().property(u => u.account)
.isoptional()
.isunicode(false)
.hasmaxlength(50);
執(zhí)行測試,更改成功。
得出結(jié)論:在實(shí)體配置時(shí),指定了為必選的字段,那么更新操作時(shí),構(gòu)造實(shí)例一定要對必選(isrequired())字段賦值。
上述測試中還有一個(gè)值得考慮的細(xì)節(jié),構(gòu)造user實(shí)例的時(shí)候,只對id,email進(jìn)行了賦值,而沒有對其他屬性進(jìn)行賦值,那么為什么會成功呢?那么必定是未進(jìn)行任何設(shè)置的實(shí)體屬性默認(rèn)是isoptional()。這跟表結(jié)構(gòu)中的字段類型設(shè)置為not null有無關(guān)聯(lián)呢,從測試結(jié)果看就本類應(yīng)用無必然聯(lián)系。
總結(jié):
a.實(shí)體配置中指定了實(shí)體屬性為isrequired(),更新操作構(gòu)造類的實(shí)例時(shí)必對此屬性賦值。
b.不進(jìn)行配置的實(shí)體屬性默認(rèn)為isoptional()
c.表結(jié)構(gòu)中字段是否為not null對上述規(guī)則無影響。
2 更新報(bào)錯(cuò):
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
實(shí)體屬性配置如上例所示。
操作代碼:
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(); } |
執(zhí)行操作
涉及到兩次修改操作,兩次操作構(gòu)造了兩個(gè)實(shí)例,但是實(shí)例的屬性id有相同的值。
如果兩次操作的是同一個(gè)實(shí)例,而不是不同的實(shí)例,那么不會拋出異常,代碼如下:
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 未給主鍵賦值或賦給主鍵一個(gè)不存在的值,拋出異常
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(); } |
運(yùn)行上述代碼,拋出異常信息如下,注意異常類型居然是system.data.entity.infrastructure.dbupdateconcurrencyexception,看上去像是并發(fā)問題,但實(shí)際卻不是!
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.
賦給主鍵一個(gè)不存在的值,令id=4(在數(shù)據(jù)庫表中不存在id為4的一條記錄)拋出的異常與上面的相同。
4 字段超長拋出異常:system.data.entity.validation.dbentityvalidationexception
表中nickname 字段定義為50個(gè)字符,現(xiàn)在賦值超過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(); } |
運(yùn)行程序報(bào)錯(cuò):
一層一層點(diǎn)開,查看具體原因:
原文鏈接:https://www.cnblogs.com/hdwgxz/p/7897031.html