2010-01-30 3 views
2

저는 LINQ to SQL 클래스 위에있는 프레젠테이션 모델을 사용하여 RIA 서비스를 통해 데이터를 공유하고 있습니다. Silverlight 클라이언트에서 몇 개의 새로운 항목 (앨범과 아티스트)을 만들고 서로 연관 시켰습니다 (앨범을 아티스트의 앨범 컬렉션에 추가하거나 아티스트 속성을 설정하여 앨범 중 하나가 작동 함) 컨텍스트에 추가하고 변경 사항을 제출했습니다.RIA 서비스 : 여러 프레젠테이션 모델 개체 삽입

서버에 두 개의 별도 Insert 호출이 있습니다. 하나는 앨범 용이고 다른 하나는 아티스트 용입니다. 이러한 엔티티는 새로운 것으로 ID 값이 모두 기본 int 값 (0 - 내 DB에 따라 DB의 유효한 ID 일 수 있음)에 설정됩니다. ID를 설정하지 않으면 클라이언트의 새 엔티티에 대한 앨범 삽입물에 아티스트가 포함되어 있고 아티스트 삽입물에 앨범이 포함되어 있어도 엔티티와 L2S 컨텍스트가 모두 인식하기 때문에 RIA 서비스를 통해 LINQ to SQL 클래스를 전송하면이 모든 작업이 정상적으로 작동합니다. 그러나 내 사용자 지정 프레 젠 테이션 모델 개체를 사용하면 LICQ to SQL 클래스 으로 변환하여 프로세스에서 연결을 유지해야 L2S 컨텍스트에 추가 할 수 있습니다.

간단히 말하면, 내가 말할 수있는 한, 이것은 불가능합니다. 각 엔티티는 자체 삽입 호출을 가져 오지만 ID가 없기 때문에 연관을 잃어 버리기 때문에 하나의 엔티티를 삽입 할 수는 없습니다. 데이터베이스에서 GUID 식별자를 사용하면 클라이언트에서 설정할 수 있기 때문에 다른 이야기가됩니다.

이것이 가능합니까 아니면 다른 디자인을 추구해야합니까? 올바른 부모 - 자식 연결을 작성하는 경우

답변

3

, 당신은 단지 삽입 된 프리젠 테이션 모델 (PM) -entity 관계를 추적해야합니다 :

오후의 :

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); 
} 
... 

는, 그것이 ParentID이있을 것이다. 새 ID 인 경우 상위 ID는 null입니다. Child.Parent를 새로운 부모의 참조로 설정하면 RIA는 서버에 보낸 후 참조를 보존하려고한다는 것을 이해합니다. 서버

DomainService :

여기
[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가 설정되지 않은 새로 삽입 된 엔티티 간의 관계를 저장합니다. 트랜잭션과 DB에 대한 단일 호출에서이 작업을 수행하므로 모든 엔터티가 삽입 된 후에 만 ​​ID가 설정됩니다. 관계를 저장함으로써 Child PM은 데이터베이스를 사용하여 부모 PM의 엔티티 버전을 찾을 수 있습니다. Child 엔티티가 Parent 엔티티의 Children 컬렉션에 추가되고 LINQToSQL 또는 LINQToEnityFramework가 외부 키를 처리해야합니다.

두 번째 부분은 트랜잭션이 커밋 된 후 변경 내용을 연결합니다. 부모와 자식이 모두 제출되는 시나리오에서는 하위에 ParentID 외래 키를 설정해야합니다. 이것은 지금까지 내가 말할 수있는 답변입니다 http://blogs.msdn.com/deepm/archive/2009/11/20/wcf-ria-services-presentation-model-explained.aspx

+0

, 그래서 게시 주셔서 감사합니다 다음 ChangeSet.Associate()에서

내 정보는에서왔다.나는이 일을 할 때 비슷한 것을 우연히 발견했다고 생각하지만 실제로 문제는 단순히 부모/자식 관계가 단순한 것보다 복잡한 개체 그래프로 작업하고 있다고 생각합니다. 그러한 종류의 복잡성을 처리하기 위해 종류의 솔루션이 확장 될 것입니다. – nlawalker

관련 문제