我真的对此感到疯狂。我从HTML中收到一个"父亲"的数据。实体,以及三个子实体的数据。
在我的模型绑定器中,我为关系创建存根实体,仅包含主键。
这是我的ModelBinder代码:
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
DefaultModelBinder binder = new DefaultModelBinder();
var estimate = (Estimate)binder.BindModel(controllerContext, bindingContext);
estimate.Id = Guid.NewGuid();
estimate.OwnerSociety = ModelBinderHelper.MapComplexType<OwnerSociety, int>(controllerContext, "OwnerSociety", int.Parse, c => c.IDOwnerSociety);
estimate.EstimateType = ModelBinderHelper.MapComplexType<EstimateType, Guid>(controllerContext, "EstimateType", Guid.Parse, c => c.Id);
estimate.Brand = ModelBinderHelper.MapComplexType<Brand, int>(controllerContext, "Brand", int.Parse, c => c.IDBrand);
estimate.FromAccount = ModelBinderHelper.MapComplexType<User, int>(controllerContext, "FromAccount", int.Parse, c => c.IDUser);
estimate.ManagerDirector = ModelBinderHelper.MapComplexType<User, int>(controllerContext, "ManagerDirector", int.Parse, c => c.IDUser);
estimate.Projects.Add(new Project
{
StrategicPlanner = ModelBinderHelper.MapComplexType<User, int>(controllerContext, "StrategicPlanner_1", int.Parse, c => c.IDUser),
Activity = ModelBinderHelper.MapComplexType<Activity, int>(controllerContext, "Activity_1", int.Parse, c => c.IDActivity),
ProjectState = ModelBinderHelper.MapComplexType<ProjectState, int>(controllerContext, "ProjectState_1", int.Parse, c => c.IDProjectState),
StartDate = DateTime.Now,
Name = "XXX1",
Brand = estimate.Brand,
ProjectTypes = new ProjectTypes { IDProjectType = 1 },
Consuntivo = 0,
Order = 1
});
estimate.Projects.Add(new Project
{
StrategicPlanner = ModelBinderHelper.MapComplexType<User, int>(controllerContext, "StrategicPlanner_2", int.Parse, c => c.IDUser),
Activity = ModelBinderHelper.MapComplexType<Activity, int>(controllerContext, "Activity_2", int.Parse, c => c.IDActivity),
ProjectState = ModelBinderHelper.MapComplexType<ProjectState, int>(controllerContext, "ProjectState_2", int.Parse, c => c.IDProjectState),
StartDate = DateTime.Now,
Name = "XXX2",
Brand = estimate.Brand,
ProjectTypes = new ProjectTypes { IDProjectType = 1 },
Consuntivo = 0,
Order = 2
});
estimate.Projects.Add(new Project
{
StrategicPlanner = ModelBinderHelper.MapComplexType<User, int>(controllerContext, "StrategicPlanner_3", int.Parse, c => c.IDUser),
Activity = ModelBinderHelper.MapComplexType<Activity, int>(controllerContext, "Activity_3", int.Parse, c => c.IDActivity),
ProjectState = ModelBinderHelper.MapComplexType<ProjectState, int>(controllerContext, "ProjectState_3", int.Parse, c => c.IDProjectState),
StartDate = DateTime.Now,
Name = "XXX3",
Brand = estimate.Brand,
ProjectTypes = new ProjectTypes { IDProjectType = 1 },
Consuntivo = 0,
Order = 3
});
return estimate;
}
当我尝试简单地附加我的父实体时,声明它并将子属性声明为Added,我得到&#34;在objectstatemanager中已经有一个对象具有相同的键&#34;。如果我尝试插入没有子节点的父实体,它就可以工作。
我尝试了另一种&#34;方式&#34;。以下代码:
public Estimate CreateEstimate(Estimate toCreate)
{
var brand = Brands.First(c => c.IDBrand == toCreate.Brand.IDBrand);
var estimateType = EstimateTypes.First(c => c.Id == toCreate.EstimateType.Id);
var account = Users.First(c => c.IDUser == toCreate.FromAccount.IDUser);
var manager = Users.First(c => c.IDUser == toCreate.ManagerDirector.IDUser);
var owner = OwnerSocieties.First(c => c.IDOwnerSociety == toCreate.OwnerSociety.IDOwnerSociety);
toCreate.Brand = brand;
toCreate.EstimateType = estimateType;
toCreate.FromAccount = account;
toCreate.ManagerDirector = manager;
toCreate.OwnerSociety = owner;
foreach (var project in toCreate.Projects)
{
project.Activity = Activities.First(c => c.IDActivity == project.Activity.IDActivity);
project.ProjectState = ProjectStates.First(c => c.IDProjectState == project.ProjectState.IDProjectState);
project.StrategicPlanner = Users.First(c => c.IDUser == project.StrategicPlanner.IDUser);
project.ProjectTypes = _entities.ProjectTypes.First();
}
_entities.EstimateSet.AddObject(toCreate);
return toCreate;
}
但它不起作用,告诉我&#34; INSERT on table&#34; Activities&#34;失败,因为列&#34;名称&#34;不能成为&#34;。但它确实不应该在Activity表中插入任何内容,实际上我正在从DB中检索Activity项并使用它们。
有趣,以下代码有效:
public Estimate CreateEstimate(Estimate toCreate)
{
var estimate = new Estimate();
var brand = Brands.First(c => c.IDBrand == toCreate.Brand.IDBrand);
var estimateType = EstimateTypes.First(c => c.Id == toCreate.EstimateType.Id);
var account = Users.First(c => c.IDUser == toCreate.FromAccount.IDUser);
var manager = Users.First(c => c.IDUser == toCreate.ManagerDirector.IDUser);
var owner = OwnerSocieties.First(c => c.IDOwnerSociety == toCreate.OwnerSociety.IDOwnerSociety);
estimate.Id = toCreate.Id;
estimate.Brand = brand;
estimate.EstimateType = estimateType;
estimate.FromAccount = account;
estimate.ManagerDirector = manager;
estimate.OwnerSociety = owner;
estimate.Date = toCreate.Date;
estimate.Subject = toCreate.Subject;
estimate.Status = toCreate.Status;
estimate.Language = toCreate.Language;
foreach (var project in toCreate.Projects)
{
var project1 = new Project();
project1.Activity = Activities.First(c => c.IDActivity == project.Activity.IDActivity);
project1.ProjectState = ProjectStates.First(c => c.IDProjectState == project.ProjectState.IDProjectState);
project1.StrategicPlanner = Users.First(c => c.IDUser == project.StrategicPlanner.IDUser);
project1.StartDate = project.StartDate;
project1.Name = project.Name;
project1.Brand = brand;
project1.ProjectTypes = _entities.ProjectTypes.First();
estimate.Projects.Add(project1);
}
_entities.EstimateSet.AddObject(estimate);
return toCreate;
}
但这意味着重新创建父实体,复制值,然后重新创建每个子实体,复制值,将其分配给父实体等等。这很痛苦,我不想要写这样的详细代码。
ORM应该让我免除为CRUD操作编写大量代码的痛苦,但似乎情况并非如此。
任何人都可以帮助我?
答案 0 :(得分:1)
我遇到了完全相同的问题,并且在断开连接的场景中尝试使用EF时遇到了同样的问题。我以与你一样的方式解决了它:重新加载对象,并“重放”域对象上的更改(你必须应用一个技巧来使乐观并发工作)。这是我找到的唯一方法。
使这项工作的另一种方法是将原始实体与修改后的实体一起发送。然后您不必重新加载它,只需附加原始实体并重播更改。但是如果你发送两次所有数据,我不确定开销,不太喜欢。
任何其他方式,只是失败,崩溃,因为它似乎混淆了上下文,即使它们已经被处理掉了。