gpt4 book ai didi

wcf-ria-services - RIA 服务 : Inserting multiple presentation-model objects

转载 作者:行者123 更新时间:2023-12-04 06:59:07 28 4
gpt4 key购买 nike

我正在使用基于 LINQ to SQL 类的演示模型通过 RIA 服务共享数据。在 Silverlight 客户端上,我创建了几个新实体(专辑和艺术家),将它们相互关联(通过将专辑添加到艺术家的专辑收藏,或在专辑上设置 Artist 属性 - 任一作品),添加他们到上下文,并提交更改。

在服务器上,我收到两个单独的 Insert 调用——一个是专辑,一个是艺术家。这些实体是新的,因此它们的 ID 值都设置为默认的 int 值(0 - 请记住,这取决于我的数据库,这可能是数据库中的有效 ID),因为据我所知您没有设置 ID对于客户端上的新实体。如果我通过我的 RIA 服务将 LINQ 转移到 SQL 类,这一切都会正常工作,因为即使专辑插入包含艺术家,艺术家插入包含专辑,两者都是实体并且 L2S 上下文识别它们。但是,对于我的自定义表示模型对象,我需要将它们转换回 LINQ to SQL 类,以维护流程中的关联,以便将它们添加到 L2S 上下文中。

简而言之,据我所知,这是不可能的。每个实体都有自己的 Insert 调用,但您无法只插入一个实体,因为没有 ID,关联就会丢失。如果数据库使用 GUID 标识符,那就是另一回事了,因为我可以在客户端设置这些标识符。

这是可能的,还是我应该追求另一种设计?

最佳答案

如果您创建了正确的父子关联,您只需要跟踪插入的表示模型(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。通过存储关系,子 PM 可以使用数据库找到父 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

关于wcf-ria-services - RIA 服务 : Inserting multiple presentation-model objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2166213/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com