我有一个关于将实体框架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 ....好抓! :) –