如果您创建了正确的父子关联,您只需要跟踪插入的表示模型(PM)-实体关系:
下午:
public class Parent
{
[Key]
public int? ParentID { get; set; }
[Include]
[Composition]
[Association("Parent_1-*_Child", "ParentID", "ParentID", IsForeignKey = false)]
public IEnumerable<Child> Children { get; set; }
}
public class Child
{
[Key]
public int? ChildID { get; set; }
[Include]
[Association("Parent_1-*_Child", "ParentID", "ParentID", IsForeignKey = true)]
public Parent Parent { get; set; }
}
请务必使用 [Composition] 强制 WCF RIA 调用 DomainService 上的 InsertChild 方法。
银光:
...
public Child NewChild(Parent parent)
{
return new Child
{
ParentID = parent.ParentID,
Parent = parent,
};
}
...
public void SubmitChanges()
{
DomainContext.SubmitChanges(SaveComplete, null);
}
...
如果 Parent 不是新的,它将有一个 ParentID。如果它是新的,则父 ID 将为空。通过将 Child.Parent 设置为新 Parent 的引用,RIA 了解您尝试执行的操作,从而在将引用发送到服务器后保留该引用。
服务器上的域服务:
[EnableClientAccess]
public class FamilyDomainService : DomainService
{
private readonly IDictionary<object, EntityObject> _insertedObjectMap;
public void InsertParent(Parent parent)
{
ParentEntity parentEntity = new ParentEntity();
ObjectContext.AddToParents(parentEntity);
_insertedObjectMap[parent] = parentEntity;
ChangeSet.Associate(parent, parentEntity, (p, e) => p.ParentID = e.ParentID;
}
public void InsertChild(Child child)
{
var childEntity = new ChildEntity();
if (child.ParentID.HasValue) // Used when the Parent already exists, but the Child is new
{
childEntity.ParentID = child.ParentID.GetValueOrDefault();
ObjectContext.AddToChildren(childEntity);
}
else // Used when the Parent and Child are inserted on the same request
{
ParentEntity parentEntity;
if (child.Parent != null && _insertedObjectMap.TryGetValue(child.Parent, out parentEntity))
{
parentEntity.Children.Add(childEntity);
ChangeSet.Associate(child, childEntity, (c, e) => c.ParentID = e.Parent.ParentID);
}
else
{
throw new Exception("Unable to insert Child: ParentID is null and the parent Parent cannot be found");
}
}
_insertedObjectMap[child] = childEntity;
ChangeSet.Associate(child, childEntity, (c, e) => c.ChildID = e.ChildID );
}
protected override bool PersistChangeSet()
{
ObjectContext.SaveChanges();
_insertedObjectMap.Clear();
return true;
}
}
这里有两个重要的部分。首先,“_insertedObjectMap”存储了新插入的没有设置 ID 的实体之间的关系。由于您是在事务和对数据库的单次调用中执行此操作,因此只有在插入所有实体后才会设置 ID。通过存储关系,Child PM可以使用数据库找到Parent PM的实体版本。Child 实体被添加到 Parent 实体上的 Children 集合中,并且 LINQToSQL 或 LINQToEnityFramework 应该为您处理外键。
第二部分是在事务提交后关联更改。在Parent和Child都提交的场景下,一定要记得在Child上设置ParentID外键。
我来自 ChangeSet.Associate() 的信息来自:http: //blogs.msdn.com/deepm/archive/2009/11/20/wcf-ria-services-presentation-model-explained.aspx