我有一個關於將實體框架4.1 CF中的子實體添加到根實體的問題。實體框架代碼優先 - 通過聚合根添加1:很多
考慮下面的基礎設施實體基類和兩個波蘇斯:
public abstract class EntityBase<TKeyDataType>
{
[Key]
public TKeyDataType Id { get; set; }
// Equality methods ommitted for brevity...
}
public class Foo : EntityBase<int>, IAggregateRoot
{
public string Foo1 { get; set; }
public virtual ICollection<FooSibling> Siblings { get; set; }
}
public class FooSibling : EntityBase<int>
{
public string SiblingPropFoo { get; set; }
public int FooId { get; set; }
public Foo Foo { get; set; }
}
注意Foo
工具IAggregateRoot
(只是一個空洞的接口 - 把它作爲元數據的上下文中的「關於數據的數據」)。
到目前爲止,這麼好。如果我運行它,EF使用適當的1:多關係創建數據庫。
唯一的一口流利的映射我有兩個實體:
modelBuilder.Entity<Foo>()
.HasMany(x => x.Siblings)
.WithRequired(x=>x.Foo)
.WillCascadeOnDelete(true);
沒有FooSibling
沒有Foo
。吹掉一個Foo
,你吹走所有的兄弟姐妹。這件作品。
的問題是增加FooSiblings POCO到富POCO的時候,我都用獨特的負數如本服務的方法:
public ResponseBase UpdateBy(RequestBase<Foo> request)
{
ResponseBase response = new ResponseBase();
try
{
Foo foo = FooRepository.FirstOrDefault(x => x.Id == request.Entity.Id);
// Dummy adds to test associations.
// These come back on the Foo inside the request, but I'm explicitly putting them here
// for the purpose of this question.
request.Entity.Siblings.Add(new FooSibling() { Id = -2, SiblingPropFoo = "Prop1", SiblingPropFoo2 = "Prop2" });
request.Entity.Siblings.Add(new FooSibling() { Id = -1, SiblingPropFoo = "Prop1", SiblingPropFoo2 = "Prop2" });
// Update Foo's scalars and children (mapping is Foo->Foo)
foo = AutoMapper.Mapper.Map(request.Entity, foo);
UnitOfWork.Commit();
response.Success = true;
}
catch (Exception e)
{
response.Success = false;
response.Message = e.Message;
}
return response;
}
一旦UnitofWork.Commit()
被稱爲(它只是調用上下文的SaveChanges
- 這裏沒有魔法),一切都很好...
但是,如果我不使用獨特的負數一樣,只是嘗試設置其母公司,像這樣:
request.Entity.Siblings.Add(new FooSibling() { Foo = foo, SiblingPropFoo = "Prop1", SiblingPropFoo2 = "Prop2" });
request.Entity.Siblings.Add(new FooSibling() { Foo = foo, SiblingPropFoo = "Prop1", SiblingPropFoo2 = "Prop2" });
只有一個持久化到數據庫。
我知道做到這一點,而無需使用負數唯一的另一種方法是直接在服務方法使用FooSiblings DbSet:
IRepository<FooSibling> siblingRepo = new CookieCutterEntityFrameworkRepository<FooSibling>(UnitOfWork);
siblingRepo.Insert(new FooSibling() { FooId = foo, .... });
我18.11存儲庫抽象所有DbSet東西,等
但是......爲了清晰起見,剝離所有抽象和泛型伏都,問題真的歸結爲是否有方法更新我的Foo POCO(根實體)並通過一個DbSet添加新的兄弟而不使用負數? (使用純的DbContext沒有抽象)
參考:
// This works (using multiple DbSets/Repositories always make life easier...)
Ctx.Foos.Update(foo);
Ctx.FooSiblings.Add(new FooSibling() { Foo = foo, ... });
Ctx.FooSiblings.Add(new FooSibling() { Foo = foo, ... });
Ctx.SaveChanges();
// This works too (using negative number trick - foo scalar properties get
// updated and the siblings get persisted to the database properly).
foo.Siblings.Add(new FooSibling() { Id = -2, ....});
foo.Siblings.Add(new FooSibling() { Id = -1, ....});
Ctx.Foos.Update(foo);
Ctx.SaveChanges();
// This doesn't work (but it's what I'm striving for to drive everything off the root).
foo.Siblings.Add(new FooSibling() { Foo = foo });
foo.Siblings.Add(new FooSibling() { Foo = foo });
Ctx.Foos.Update(foo);
Ctx.SaveChanges();
在最後一種情況下(非工作情況下),我努力將其配置在它拿起任何變化的時尚Foo POCO本身。
我試過關閉代理服務器。而且,按照這種設置方式,上下文仍然處於整個HTTP請求生命週期的範圍內。
如果不可能,您會提出什麼建議?
感謝您的反饋朱莉。問題實際上是在我的EntityBase對象上。我覆蓋了GetHashCode方法,並在ID本身上返回HashCode ...所以0的Hashcode總是相等的。一旦我評論說,一切都是通過根源共同發射的。我同意100%負面的數字有點駭人聽聞。 – Forest
ahhhhhh ....好抓! :) –