linq 加入 case 条件
Posted
技术标签:
【中文标题】linq 加入 case 条件【英文标题】:linq join with case condition 【发布时间】:2011-02-10 06:13:35 【问题描述】:嗨,我可以知道如何在使用 linq 时选择“案例”条件吗? 注释掉的代码是我的问题。我如何把条件放在那里? 我的代码:
var r = from u in Users
join p in Payments on u.Id equals p.UserId
join soi in SaleOrderItems on p.ReferenceId equals soi.Id
//if soi.InventoryTypeId == 1
//then join i in Inventories on soi.InventoryOrCourseId equals i.Id
//elseif soi.InventorytypeId ==2
//then join c in Courses on soi.InventoryOrCourseId equals c.Id
where u.Id == 5
select new u, p, soi, either i or c;
【问题讨论】:
【参考方案1】:您必须使用一些外连接技巧来完成此操作,一种简单的方法是通过DefaultIfEmpty()
。本质上,您创建了一个内部联接,然后用缺少的行扩展它:
var r = from u in Users
join p in Payments on u.Id equals p.UserId
join soi in SaleOrderItems on p.ReferenceId equals soi.Id
join i in Inventories on new a = soi.InventoryTypeId, b = soi.InventoryOrCourseId equals new a = 1, b = i.Id into g1
from oi in g1.DefaultIfEmpty()
join c in Courses on new a = soi.InventoryTypeId, b = soi.InventoryOrCourseId equals new a = 2, b = c.Id into g2
from oc in g2.DefaultIfEmpty()
where u.Id == 5
select new u, p, soi, ic = oi ?? oc;
请注意最后一条语句ic = oi ?? oc
,因为类型不同,匿名类型将使用 System.Object 声明,因此它可以容纳两种类型,如果您想使用强类型支持,也许更好的选择是同时返回两者oc和ic,然后测试。你最好根据你如何使用这个查询来决定。
【讨论】:
@mmix 嗨,我收到此错误“连接子句中的表达式之一不正确。调用“GroupJoin”时类型推断失败。”在新的 a... 上加入 i 库存soi.InventoryTypeId
是什么类型?既然我想象type(soi.InventoryOrCourseId)
等于type(Inventory.Id)
,那么一定是soi.InventoryTypeId
不是int
。如果是这样,用适当的类型后缀(U、L 等)装饰常量 1 和 2
@mmix: 是的,它们都是 int
它可能不是int
,而是可以为空的int,int?
,它经常被遗漏。尝试将常量转换为(int?)。该错误非常具体,只能是类型不匹配。我在线发布了一个代码 sn-p,它在离线数组集上执行此查询。 codepad.org/PGhG9i2S
奇怪!!我已将我的代码更改为此 - 在新的 a = Convert.ToInt16(soi.InventoryTypeId), b = Convert.ToInt16(soi.InventoryOrCourseId) 上加入我的 db.Inventories 等于新 a = (int)InventoryTypes.Product , b = i.Id 进入 g1 .. 但它仍然给我同样的错误。我已经再次确认我所有的表 SaleOrderItems ,Inventories 的 id 都是 int。以上是关于linq 加入 case 条件的主要内容,如果未能解决你的问题,请参考以下文章
在 HiveQL 的“on”子句中使用 case 语句进行条件连接