我在使用 Automapper 和 Entity Framework 时遇到了两个问题,我想知道我的解决方案是否是最好的。
语境 :
我有一个ObjectA
which 有一个列表,ObjectB
其中又有一个ObjectC
.
ObjectC
是数据库中的一个列表,就像国家一样。我可以更改但我不添加想要添加ObjectC
。ObjectB
ObjectC
我使用 MVVM 并ObjectB
在数据网格中列出。有组合框可供选择ObjectC
。
我想保存ObjectA
并ObjectB
同时使用 Automapper 和事务。
public void SaveObjectA(ObjectA p_ObjectA)
{
OpenTransaction();
var l_Provider = new DataProvider<DB.ObjectA>(Context);
var l_ObjectA = l_Provider.FindById(p_ObjectA.ID);
Mapper.Map(p_ObjectA, l_ObjectA);
CloseTransaction();
}
实体框架类:
public partial class ObjectA
{
public ObjectA()
{
this.ObjectB = new HashSet<ObjectB>();
}
public System.Guid ID { get; set; }
public virtual ICollection<ObjectB> ObjectB { get; set; }
}
public partial class ObjectB
{
public System.Guid ID { get; set; }
public System.Guid ObjectCID { get; set; }
public virtual ObjectC ObjectC { get; set; }
}
public partial class ObjectC
{
public System.Guid ID { get; set; }
public string Name { get; set; }
}
DTO 类:
public class ObjectA : ObjectBase
{
public ObjectA ()
{
ObjectB = new Collection< ObjectB >();
}
public virtual ICollection<ObjectB> ObjectB { get; set; }
}
public class ObjectB : ObjectBase
{
private ObjectC _ObjectC { get; set; }
public virtual ObjectC ObjectC
{
get
{
return _ObjectC;
}
set
{
_ObjectC = value;
}
}
}
public class ObjectC : ObjectBase
{
public string Name { get; set; }
}
public abstract class ObjectBase
{
public Guid ID { get; set; }
}
第一个问题:当我保存时ObjectB
,实体框架会尝试插入ObjectC
。但ObjectC
已经存在。我不想要插入但要更新。
我的解决方案(见论坛):
Mapper.CreateMap<ObjectB, DB.ObjectB>()
.ForMember(pro=>pro.ObjectC, opt=>opt.Ignore());
但我不明白,因为如果我忽略ObjectC
,ObjectC
不应该更新。但是,它可以工作(即:更新正常,他不会尝试在数据库中添加一行,Automapper/EF 可以在数据库中找到并ObjectC
更新...)ObjectCID
ObjectB
注意:它也适用于我的第二个问题的第一点的解决方案。
第二个问题:当我在数据网格上更新、添加或删除一行时,我想将更改保存在数据库中。
更新:与第一个问题相同:该行已经存在。
Mapper.CreateMap<ObjectB, DB.ObjectB>() .ConstructUsing(s => Context.Set<DB.ObjectB>().Find(s.ID));
我认为,解决方案是从数据库中附加正确的行,然后填充属性。
所以我用
ConstructUsing
查找行。添加:然后,ID 为空,我无法保存新行
Mapper.CreateMap<ObjectB, DB.ObjectB>() .ConstructUsing(s => Context.Set<DB.ObjectB>().Find(s.ID) ?? Context.Set<DB.ObjectB>().Create())
在该行不存在的情况下,我必须创建(并附加)一个对象到上下文。
删除:在数据网格上删除的行不会在数据库中删除:
Mapper.CreateMap<ObjectA, DB.ObjectA>() .ConstructUsing(s => Context.Set<DB.ObjectA>().Create()) .AfterMap ( (bef, aft) => aft.ObjectB.ToList() .Where(x => !bef.ObjectB.Select(z=>z.ID).Contains(x.ID)) .ToList() .ForEach(ele => Context.ObjectB .Remove(Context.ObjectB.Find(ele.ID))) );
所以,它有效,但我想知道你会怎么做,更简单的方法。