[英]Entity Framework Core 2.0.1 Eager Loading on all nested related entities
[英]Persisting Entity Framework nested/related entities
我有以下實體:
public class ModuleCriteria
{
public int ModuleCriteriaId { get; set; }
public string Criteria { get; set; }
public List<ModuleCriteriaLookup> ModuleCriteriaLookups { get; set;
}
}
public class ModuleCriteriaLookup
{
public int ModuleCriteriaLookupId { get; set; }
public int ModuleCriteriaId { get; set; } // ** (Foreign Key) **
public int SiteId { get; set; }
public string CategoryId { get; set; }
public ModuleCriteria ModuleCriteria { get; set; }
}
我的Context
類中有以下EF配置(為簡潔起見進行了編輯):
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
base.OnModelCreating( modelBuilder );
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<ModuleCriteriaLookup>().HasRequired( mc => mc.ModuleCriteria );
// I tried adding the below line but it made no difference.
//modelBuilder.Entity<ModuleCriteria>().HasMany( mc => mc.ModuleCriteriaLookups );
}
...並且在Context
類中定義了以下DbSet
屬性:
public DbSet<ModuleCriteria> ModuleCriteria { get; set; }
public DbSet<ModuleCriteriaLookup> ModuleCriteriaLookup { get; set; }
我有一個CriteriaRepository
類,該類具有Save
方法,用於持久Save
我的ModuleCriteria
實體的更改:
public void Save( ModuleCriteria moduleCriteria )
{
using ( var ctx = new MyAppContext() )
{
ctx.Entry( moduleCriteria ).State = moduleCriteria.ModuleCriteriaId == 0 ? EntityState.Added : EntityState.Modified;
ctx.SaveChanges();
}
}
沒有ModuleCriteria
對象也可以存在ModuleCriteriaLookup
對象,但是ModuleCriteriaLookup
對象必須與現有的ModuleCriteria
對象相關(與ModuleCriteriaId
相關)。
您可以具有多個ModuleCriteraLookup
對象,這些對象都與同一個ModuleCriteria
對象相關。
我想要並期望使用EF的行為是:
1)如果我創建一個新的ModuleCriteria
對象(沒有任何ModuleCriteriaLookups
),請在我的存儲庫中調用Save
方法,我希望在數據庫中看到新的ModuleCriteria
記錄,而在數據庫中沒有相關的ModuleCriteriaLookup
記錄。
2)如果我創建一個新的ModuleCriteria
對象並為其分配一個List<ModuleCriteriaLookup>
,請在我的存儲庫中調用Save方法,我希望在db中看到新的ModuleCriteria
記錄,並在db中看到ModuleCriteria
x個新的ModuleCriteriaLookup
行。特定的ModuleCriteria
。
3)如果我添加/編輯/刪除任何的ModuleCriteriaLookup
是與我的一個對象ModuleCriteria
對象,然后調用Save
的方法在我的倉庫,我希望看到任何的ModuleCriteria
的刪除ModuleCriteriaLookup
對象從下列位置移除數據庫,添加任何新的和編輯的只是為了得到更新。
因此,我只需要擔心的是,對於給定的ModuleCriteria
,無論ModuleCriteria.ModuleCriteriaLookups
屬性包含什么,只需在存儲庫中為ModuleCriteria
對象調用Save方法,這就會反映在數據庫的2個表中。
不幸的是,目前,如果我要添加一個新的帶有關聯的List<ModuleCriteriaLookup>
ModuleCriteria
對象,它將很好地在數據庫中添加ModuleCriteria
和x ModuleCriteriaLookup
行。 但是,當我要編輯或刪除ModuleCriteria.ModuleCriteriaLookups
屬性中的條目時,這並沒有反映在數據庫中。 ModuleCriteriaLookups
行沒有任何ModuleCriteriaLookups
。
我不確定問題出在哪里,是否是EF映射配置,還是與存儲庫的工作方式有關?
問題位於存儲庫中。 DbContext
需要意識到實體的存在。 因此,在編輯和/或刪除實體時,首先需要從數據庫中獲取實體。
該描述明確指出:
.Entry
屬性從上下文返回由上下文跟蹤的對象。
由於您是在創建上下文之后直接使用此屬性的,因此上下文不會跟蹤這些實體,因此不會知道某些更改。 因此無法生成正確的SQL語句。
有幾種方法可以解決此問題,具體取決於設計的其余部分。
刪除它的一種方法是:
public void DeleteModuleCriteriaLookup(ModuleCriteriaLookup[] lookups)
{
using (var ctx = new MyAppContext())
{
var moduleCriteriaId = lookups.First().ModuleCriteriaId;
var moduleCritria = (
from criteria in ctx.ModuleCriteria
where criteria.ModuleCriteriaId == moduleCriteriaId
select criteria
).Single();
var lookupIdsToDelete = lookups.Select(l => l.ModuleCriteriaLookupId);
var lookupsToDelete = (
from lookup in moduleCritria.ModuleCriteriaLookups
where lookupIdsToDelete.Contains(lookup.ModuleCriteriaLookupId)
select lookup
).ToArray();
foreach (var lookup in lookupsToDelete)
{
moduleCritria.ModuleCriteriaLookups.Remove(lookup);
}
ctx.SaveChanges();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.