如何在子实体对象中包含父对象列表

时间:2011-03-16 12:30:09

标签: silverlight linq frameworks join entity

我的数据库中有以下表格

Table1: tblAddressType (Id, Name)

Table2: tblAddressDtls (Id, AddressTypeId, Address1)

我将继续加入上述两个表,以获取所有地址类型列表和相应的地址详细信息,如下所示

SQL Query:    

    select t1.*, t2.*
    from tblAddressType t1
    left outer join tblAddressDtls t2 on t1.Id = t2.AddressTypeId and t2.Id = 1;

对于上面的表,我创建了POCO实体类,如下所示:

[Table("tblAddressType ")]
public partial class AddressType
{

    [Key]
    [Column(Name="ID")]
    public int ID { get; set; }

    [Required]
    [Column(Name = "Name")]
    public virtual string Name {get; set;}

    [Include]
    [Association("AddressTypeAddress", "ID", "AddressTypeId")]
    public virtual ICollection<Address> Addresses { get; set; }
}


[Table("tblAddress", SchemaName="dbo")]
public class Address
{
    [Column(Name="ID")]
    public int ID { get; set; }

    [Column(Name = "AddressTypeId")]
    public int? AddressTypeId{ get; set; }

    [Column(Name = "Address1")]
    public string Address1{ get; set; }

    [Include]
    [Association("AddressTypeAddress", "AddressTypeId", "ID", IsForeignKey = true)]
    public virtual AddressType AddressType { get; set; }

}

并且,为了获取上面的sql查询中显示的数据,我在我的服务代码中编写了以下LINQ查询,此查询根据需要返回数据:

var qry = (from p in dbContext.AddressTypes
           join pa in (from t in dbContext.Addresses 
                       where t.ID == 1 select t)
                       on p.ID equals pa.AddressTypeId into ppa
           from t in ppa.DefaultIfEmpty()
           select t).AsQueryable();

现在,我想写一个名为“GetAddressById(int addressId)”的域服务方法,它应该返回匹配的Address对象以及AddressType对象列表,因为我需要将“AddressType”对象列表绑定到下拉列表添加/编辑地址屏幕中的框。

I wanted to include and fetch list of "AddressType" objects data at the time of 
fetching Address object data itself to avoid round-trip to server 
in my silverlight client app. 

请建议我实现此功能的最佳方式?

2 个答案:

答案 0 :(得分:2)

我假设在数据库中,Addresses与AddressTypes有关系,并且您再次使用EntityFramework。

GetAddressById(int addressId){
   return dbContext.Address.SingleOrDefault(a => a.ID == addressId).Include("AddressTypes");
}

该行代码现在将获得一个id为addressId的地址,如果没有则会返回null,或者如果返回的更多会抛出异常,Include会告诉EF你也想要AddressTypes当你获得地址时加载并创建一个适当的连接来实现这一点,所有这些都将成为对数据库的单个查询并获得你想要的结果。

<强> OLD: 假设我们希望AddressType及其所有地址只需一次调用db(假设您使用EntityFramework),我们就会调用类似

的方法
GetAddressTypeIncludingAddresses(int id){
    return _context.AddressType.Include("Addressess"); 
 /*if you use ctp5 of ef code first you should even be able to do (at => at.Addresses) in the include */
}

然后当你拥有它时,只需使用它addressType.Idforeach(var address in addressType.Addresses){}等。

我希望我理解你的问题,如果不再试一次,我会编辑我的答案。

答案 1 :(得分:1)

您可以通过在数据库中创建一个返回多个结果集的存储过程来完成此操作。首先是获得所需孩子和父母的人,然后是获得父母名单的人。然后你可以使用这里描述的解决方法:

http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/02/04/linq-to-sql-returning-multiple-result-sets.aspx

这使您可以获得结果的每个部分。

顺便说一下,您的查询不需要左连接。由于where子句引用了右边的表,因此在连接的右侧永远不会得到空值。改为使用内连接。