Linq to SQL:在相关表中按值排序

时间:2009-01-03 08:30:25

标签: linq linq-to-sql

我有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添加这些产品,但这样就不会保留第一部分的排序。

处理此问题的最佳方法是什么?

感谢。

3 个答案:

答案 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;