我有2个表格,简化形式如下:
Products(
id: int,
name: varchar
);
ProductSpecs(
product_id: int,
spec_name: varchar,
spec_value: int
);
现在我需要通过某些规范项的值(例如“价格”)对产品(在linq到sql中)进行排序。所以我做这样的事情
var products = from p in db.Products
from ps in p.ProductsSpecs
where ps.spec_name == "price"
orderby ps.spec_value
select p;
问题在于,如果没有这样的具有spec_name“price”的ProductSpec,则根本不包含该产品。我可以使用Union或Concat添加这些产品,但这样就不会保留第一部分的排序。
处理此问题的最佳方法是什么?
感谢。
答案 0 :(得分:8)
首先,我建议您在纯SQL中将其作为函数或存储过程执行此操作,然后通过linq访问它,或者将price列添加到product表中。即使价格为NULL,价格似乎也是添加到所有产品的正常属性。
SQL:
select p.*
from products p
left outer join productspecs ps on
p.id = ps.product_id
and ps.spec_name = 'Price'
order by ps.spec_value
话虽如此,这里有一些奇怪的LINQ应该可以在你的桌面上工作(我可能有一些拼写错误的列名):
var products = from p in db.Products
join ps in (from pss in db.ProductSpecs
where pss.spec_name== "Price"
select pss
) on p.id equals ps.product_id into temp
from t in temp.DefaultIfEmpty()
orderby t.spec_value
select p;
我在上面的一些表设置上测试了这个并创建了5个产品,其中三个产品的价格在不同的值订单中,这个LINQ就像上面的SQL一样对它们进行排序并返回了空结果行。
希望这有效!
答案 1 :(得分:0)
在普通的SQL中,你使用LEFT OUTER JOIN。这样可以保留左侧表格中显示的行(首先列出的行),即使右侧表格中没有匹配的行(列出的第二行和外部连接的行)也是如此。对于应该但不存在于右侧表中的值,您最终会得到空值。因此,缺少价格的商品的价格将显示为NULL。
在LINQ to SQL中转换为另一个问题。
您可能会考虑让产品没有价格是否合理。你正在模仿名为EAV的东西 - 实体,属性,价值表,它们通常被认为是“不是一件好事”。
答案 2 :(得分:0)
你能不能做一个简单的加入?
var products = 来自db.Products中的p 在p.id上的db.ProductSpecs中加入ps等于ps.product_id 其中ps.spec_name ==“price” orderby ps.spec_value 选择p;