开发者

wcf ria services - poco with parent child relationship

开发者 https://www.devze.com 2023-03-19 14:07 出处:网络
I have two domain classes: Parent and Child. The Parent have a list of Child. when I use a doma开发者_运维技巧in service to retrieve a list of parent objects, I want to retrieve each parent\'s childre

I have two domain classes: Parent and Child. The Parent have a list of Child. when I use a doma开发者_运维技巧in service to retrieve a list of parent objects, I want to retrieve each parent's children.Here are the domain classes , domain service and client code:

 public class Parent
{
    private IList<Child> children;
    [Key]
    public virtual int ParentId { get; set; }
    public Parent()
    {
        children = new List<Child>();
    }
    public virtual string Name { get; set; }
    [Include()]
    [Association("ParentChild", "ParentId", "ChildId", IsForeignKey = false)]
    public virtual IList<Child> Children
    {
        get { return children; ; }
        set { children = value; }
    }
    public virtual void AddChild(Child child)
    {
        child.Parent = this;
        Children.Add(child);
    }
}
 public class Child
{
    [Key]
    public virtual int ChildId { get; set; }
    public virtual String Name { get; set; }
    public virtual String Action { get; set; }
    [Include]
    [Association("ParentChild", "ChildId", "ParentId", IsForeignKey = true)]
    public virtual Parent Parent { get; set; }
}

domain service:

[EnableClientAccess()]
public class ParentDomainService : DomainService
{
    public IList<Parent> GetParents()
    {
        var system = new Parent() { ParentId = 1, Name = "System1" };
        system.AddChild(new Child()
                                 {
                                     Action = "Action1",
                                     ChildId = 3,
                                     Name = "File1"
                                 });
        system.AddChild(new Child()
        {
            Action = "Action2",
            ChildId = 5,
            Name = "File2"
        });
        var result = new List<Parent>() {system};
        return result;

    }
}

silverlight gui code: just a button with an event handler:

 private void button1_Click(object sender, RoutedEventArgs e)
    {
        var context = new ParentDomainContext();
        var entityQuery = context.GetParentsQuery();
        context.Load(entityQuery,OnParentsLoaded,null);
    }

    private void OnParentsLoaded(LoadOperation<Parent> obj)
    {
        var fileSystem = obj.Entities.FirstOrDefault();

        if (fileSystem != null)
        {
            var memoryFiles = fileSystem.Children.ToList();

        }
    }

the children are missing!

Please, If someone can help, I can't see what is missing.

The generated code on the client:

/// <summary>
/// The 'Child' entity class.
/// </summary>
[DataContract(Namespace="http://schemas.datacontract.org/2004/07/WordsBuilder.DomainModel")]
public sealed partial class Child : Entity
{

    private string _action;

    private int _childId;

    private string _name;

    private EntityRef<Parent> _parent;

    #region Extensibility Method Definitions

    /// <summary>
    /// This method is invoked from the constructor once initialization is complete and
    /// can be used for further object setup.
    /// </summary>
    partial void OnCreated();
    partial void OnActionChanging(string value);
    partial void OnActionChanged();
    partial void OnChildIdChanging(int value);
    partial void OnChildIdChanged();
    partial void OnNameChanging(string value);
    partial void OnNameChanged();

    #endregion


    /// <summary>
    /// Initializes a new instance of the <see cref="Child"/> class.
    /// </summary>
    public Child()
    {
        this.OnCreated();
    }

    /// <summary>
    /// Gets or sets the 'Action' value.
    /// </summary>
    [DataMember()]
    public string Action
    {
        get
        {
            return this._action;
        }
        set
        {
            if ((this._action != value))
            {
                this.OnActionChanging(value);
                this.RaiseDataMemberChanging("Action");
                this.ValidateProperty("Action", value);
                this._action = value;
                this.RaiseDataMemberChanged("Action");
                this.OnActionChanged();
            }
        }
    }

    /// <summary>
    /// Gets or sets the 'ChildId' value.
    /// </summary>
    [DataMember()]
    [Key()]
    [RoundtripOriginal()]
    public int ChildId
    {
        get
        {
            return this._childId;
        }
        set
        {
            if ((this._childId != value))
            {
                this.OnChildIdChanging(value);
                this.RaiseDataMemberChanging("ChildId");
                this.ValidateProperty("ChildId", value);
                this._childId = value;
                this.RaiseDataMemberChanged("ChildId");
                this.OnChildIdChanged();
            }
        }
    }

    /// <summary>
    /// Gets or sets the 'Name' value.
    /// </summary>
    [DataMember()]
    public string Name
    {
        get
        {
            return this._name;
        }
        set
        {
            if ((this._name != value))
            {
                this.OnNameChanging(value);
                this.RaiseDataMemberChanging("Name");
                this.ValidateProperty("Name", value);
                this._name = value;
                this.RaiseDataMemberChanged("Name");
                this.OnNameChanged();
            }
        }
    }

    /// <summary>
    /// Gets or sets the associated <see cref="Parent"/> entity.
    /// </summary>
    [Association("ParentChild", "ChildId", "ParentId", IsForeignKey=true)]
    public Parent Parent
    {
        get
        {
            if ((this._parent == null))
            {
                this._parent = new EntityRef<Parent>(this, "Parent", this.FilterParent);
            }
            return this._parent.Entity;
        }
        set
        {
            Parent previous = this.Parent;
            if ((previous != value))
            {
                this.ValidateProperty("Parent", value);
                if ((previous != null))
                {
                    this._parent.Entity = null;
                    previous.Children.Remove(this);
                }
                if ((value != null))
                {
                    this.ChildId = value.ParentId;
                }
                else
                {
                    this.ChildId = default(int);
                }
                this._parent.Entity = value;
                if ((value != null))
                {
                    value.Children.Add(this);
                }
                this.RaisePropertyChanged("Parent");
            }
        }
    }

    private bool FilterParent(Parent entity)
    {
        return (entity.ParentId == this.ChildId);
    }

    /// <summary>
    /// Computes a value from the key fields that uniquely identifies this entity instance.
    /// </summary>
    /// <returns>An object instance that uniquely identifies this entity instance.</returns>
    public override object GetIdentity()
    {
        return this._childId;
    }
}

/// <summary>
/// The 'Parent' entity class.
/// </summary>
[DataContract(Namespace="http://schemas.datacontract.org/2004/07/WordsBuilder.DomainModel")]
public sealed partial class Parent : Entity
{

    private EntityCollection<Child> _children;

    private string _name;

    private int _parentId;

    #region Extensibility Method Definitions

    /// <summary>
    /// This method is invoked from the constructor once initialization is complete and
    /// can be used for further object setup.
    /// </summary>
    partial void OnCreated();
    partial void OnNameChanging(string value);
    partial void OnNameChanged();
    partial void OnParentIdChanging(int value);
    partial void OnParentIdChanged();

    #endregion


    /// <summary>
    /// Initializes a new instance of the <see cref="Parent"/> class.
    /// </summary>
    public Parent()
    {
        this.OnCreated();
    }

    /// <summary>
    /// Gets the collection of associated <see cref="Child"/> entity instances.
    /// </summary>
    [Association("ParentChild", "ParentId", "ChildId")]
    public EntityCollection<Child> Children
    {
        get
        {
            if ((this._children == null))
            {
                this._children = new EntityCollection<Child>(this, "Children", this.FilterChildren, this.AttachChildren, this.DetachChildren);
            }
            return this._children;
        }
    }

    /// <summary>
    /// Gets or sets the 'Name' value.
    /// </summary>
    [DataMember()]
    public string Name
    {
        get
        {
            return this._name;
        }
        set
        {
            if ((this._name != value))
            {
                this.OnNameChanging(value);
                this.RaiseDataMemberChanging("Name");
                this.ValidateProperty("Name", value);
                this._name = value;
                this.RaiseDataMemberChanged("Name");
                this.OnNameChanged();
            }
        }
    }

    /// <summary>
    /// Gets or sets the 'ParentId' value.
    /// </summary>
    [DataMember()]
    [Editable(false, AllowInitialValue=true)]
    [Key()]
    [RoundtripOriginal()]
    public int ParentId
    {
        get
        {
            return this._parentId;
        }
        set
        {
            if ((this._parentId != value))
            {
                this.OnParentIdChanging(value);
                this.ValidateProperty("ParentId", value);
                this._parentId = value;
                this.RaisePropertyChanged("ParentId");
                this.OnParentIdChanged();
            }
        }
    }

    private void AttachChildren(Child entity)
    {
        entity.Parent = this;
    }

    private void DetachChildren(Child entity)
    {
        entity.Parent = null;
    }

    private bool FilterChildren(Child entity)
    {
        return (entity.ChildId == this.ParentId);
    }

    /// <summary>
    /// Computes a value from the key fields that uniquely identifies this entity instance.
    /// </summary>
    /// <returns>An object instance that uniquely identifies this entity instance.</returns>
    public override object GetIdentity()
    {
        return this._parentId;
    }
}


The associations you defined are incorrect and you need to add some properties to your domain classes to fix the associations.

First off you should add a property ParentId to your child class to store the id of the parent entity and then change the associations in the parent and child class and fix up the AddChild method. It should look like this (I renamed properties):

public class Parent {
  private IList<Child> children;

  public Parent()    {
    children = new List<Child>();
  }

  [Key]
  public virtual int Id { get; set; }

  public virtual string Name { get; set; }

  [Include()]
  [Association("Children", "Id", "ParentId")]
  public virtual IList<Child> Children
  {
    get { return children; ; }
    set { children = value; }
  }

  public virtual void AddChild(Child child)
  {
    child.Parent = this;
    child.ParentId = this.Id;
    Children.Add(child);
  }
}

public class Child {
  [Key]
  public virtual int Id { get; set; }

  public virtual int ParentId {get;set;}

  public virtual String Name { get; set; }

  public virtual String Action { get; set; }

  [Include]
  [Association("Parent", "ParentId", "Id")]
  public virtual Parent Parent { get; set; }
}

If you apply those changes the hierarchical structure of your entities should be respected and the children are included in your load operation.

0

精彩评论

暂无评论...
验证码 换一张
取 消