【问题标题】:LINQ Join query (with nullable ref between table)LINQ 连接查询(表之间的引用可以为空)
【发布时间】:2012-11-12 10:16:56
【问题描述】:

我有 3 张桌子。

例如客户公司地址

  • 客户已获得公司的参考。

  • 公司有 2 个可以为空的地址引用(账单和运输),因此在某些情况下地址可能不存在。

我需要进行连接查询,但如果Company.BillingAddressCompany.ShippingAddress 等于null,我不会得到所有数据。

我试过了(但它是错误的查询):

var res = (from client in context.Clients
    join clientCompany in context.Companies 
    on client.ClientCompanyId equals clientCompany.Id

    into clientCompanyJoin

    from company in clientCompanyJoin
    join addressBilling in context.Addresses
    on company.BillingAddressId equals addressBilling.Id

    join addressShipping in context.Addresses
    on company.ShippingAddressId equals addressShipping.Id

    select new
    {
        Client = client,
        Company = company,
        BillingAddress = ???????
        ShippingAddress = ???????
    }
);

您能帮我做一个连接查询或解释一下如何做吗?

谢谢。

【问题讨论】:

  • 加入什么到什么?返回类型的结构应该是什么?可以贴一些代码或伪代码吗?

标签: c# linq entity-framework nullable


【解决方案1】:

试试这段代码sn-p:

var res = (from client in context.Clients
            join clientCompany in context.Companies 
            on client.ClientCompanyId equals clientCompany.Id
            into clientCompanyJoin
            from company in clientCompanyJoin
            join addressBilling in context.Addresses
            on company.BillingAddressId equals addressBilling.Id
            where !String.IsNullOrEmpty(addressBilling.Address)
            join addressShipping in context.Addresses
            on company.ShippingAddressId equals addressShipping.Id
            where !String.IsNullOrEmpty(addressShipping.Address)
            select new
            {
                Client = client,
                Company = company,
                BillingAddress = addressBilling.Address,
                ShippingAddress = addressShipping.Address
            });

添加:根据您的 cmets,这是您需要的一段代码 sn-p。即使ShippingAddressIdBillingAddressId 等于null,您现在也可以获得您的客户公司 数据,就像Left JoinSQL 中所做的那样。

var res = (from client in context.Clients
            join company in context.Companies 
            on client.ClientCompanyId equals company.Id
            join addressBilling in context.Addresses
            on company.BillingAddressId equals addressBilling.Id 
            into addrBillingGroup
            from gAddrBilling in addrBillingGroup.DefaultIfEmpty() // left join
            join addressShipping in context.Addresses
            on company.ShippingAddressId equals addressShipping.Id 
            into addrShippingGroup
            from gAddrShipping in addrShippingGroup.DefaultIfEmpty() // left join
            select new
            {
                Client = client,
                Company = company,
                BillingAddress = 
                    gAddrBilling == null ? null : gAddrBilling.Address,
                ShippingAddress = 
                    gAddrShipping == null ? null : gAddrShipping.Address
            });

【讨论】:

  • 它不起作用。我不明白一些事情(例如!String.IsNullOrEmpty(addressBilling.Address))和 addressBilling 不包含地址字段。
  • 我认为这些地方的问题“关于 company.BillingAddressId 等于 addressBilling.Id”,因为在某些情况下 BillingAddressId 和 ShippingAddressId 等于 NULL
  • 是否要过滤 BillingAddressId 和 ShippingAddressId 为 NULL 的记录?其次,如果 BillingAddressId 和 ShippingAddressId 是整数类型,那怎么可能是 NULL?
  • 是的,如果 ShippingAddressId 或 BillingAddressId 等于 null,我仍然需要 Customer 和 Company 数据,但没有 Addresses(它应该为 null,因为左连接结果在 sql 中)。
  • 在我的模型中 ShippingAddressId 和 BillingAddressId 是可为空的 int 字段。
【解决方案2】:

我猜你想进行外部连接。以下是如何在“Northwind”数据库中为客户和订单执行此操作的示例:

var ctx = new NorthwindDataContext();
var customers = from c in ctx.Customers
    join o in ctx.Orders
    on c.CustomerID equals o.CustomerID into inJoin
    from outJoin in inJoin.DefaultIfEmpty()
    orderby c.CustomerID, outJoin.OrderID
    select new
    {
        c.CustomerID,
        c.CompanyName,
        OrderID = (int?)outJoin.OrderID,
        OrderDate = (DateTime?)outJoin.OrderDate
    };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多