檢索具有循環引用的實體時遇到問題。我的實體導航屬性不是延遲加載,所以我希望它們返回null,除非明確包含在查詢中,但是我發現當兩個實體之間存在循環引用時,情況並非如此,而是遞歸層次結構返回。防止實體框架中的循環導航屬性的自動填充
例如,假設我們有兩個實體UserEntity
和PostEntity
。 A UserEntity
可能有許多帖子,但帖子只能有一個UserEntity
。所以,配置如下:
// UserEntity configuration
HasMany(u => u.Posts)
.WithRequired(p => p.User);
如果我查詢數據庫爲任何一個UserEntity
或PostEntity
而不對各自Posts
或User
導航屬性使用Include()
,如所預期的導航屬性爲空。
但是,如果我查詢了UserEntity
,包括其PostEntity
S,一個圓形的層級返回,儘管我從來沒有要求將PostEntity.User
導航屬性填充:
using (var db = new MyDbContext())
{
var user = await db.Users
.Include(u => u.Posts)
.SingleOrDefaultAsync(u => u.ID == 0);
// The [UserEntity] contains a list of [PostEntitiy]s
// each with the [UserEntity] each with a list of [PostEntitiy]s...
// and so on.
}
這是不是太多麻煩,但是當PostEntity
個列表檢索及其UserEntity
s的包含事情就變得很奇怪:
using (var db = new MyDbContext())
{
var posts = await db.Posts
.Include(p => p.User)
.SingleOrDefaultAsync(p => p.ID == 0);
// This throws a [System.InvalidOperationException]:
// "Sequence contains more than one element"
// How can this be? The ID is unique.
var posts = await db.Posts
.Include(p => p.User)
.Where(p => p.ID == 0)
.ToListAsync();
// This returns several copies of the PostEntity
// which should be unique in the database. Is
// this a side effect of the circular reference?
}
顯然擺脫循環引用的可以解決這個問題,但如果可能的話,爲什麼保持它有益呢有幾個原因。 爲什麼EntityFramework返回這個循環層次結構,儘管只有一個單一的單向關係請求Include()
,並且爲什麼在包含它們的UserEntity
時返回多個PostEntity
?
您是將主鍵映射到屬性還是流利的API?此外,循環引用,你注意到它在代碼或調試器? –
是的,我爲我的所有配置使用流暢的API,主鍵已正確映射。數據庫首先是代碼,而不是這個循環引用問題,它完美地工作。 循環引用是由設計,但我從來沒有打算檢索遞歸hirarchy - 即我想要它的用戶的職位,或用戶的所有職位。返回的結果是遞歸的用戶帖子,用戶的帖子與帖子...等。這在調試器中是可見的,似乎也會影響查詢結果。 –