Linq到SQL:按相关表中的值排序

Linq到SQL:按相关表中的值排序,linq,linq-to-sql,Linq,Linq To Sql,我有两个简化形式的表格,如下所示: Products( id: int, name: varchar ); ProductSpecs( product_id: int, spec_name: varchar, spec_value: int ); 现在,我需要根据一些规范项的值(例如“价格”)对产品进行排序(在linq到sql中)。所以我做了类似的事情 var products = from p in db.Products fro

我有两个简化形式的表格,如下所示:

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;
问题是,如果没有这样的产品规范,规范名为“价格”,那么产品根本就不包括在内。我可以使用Union或Concat添加这些产品,但这样就不会保留第一部分的排序

处理这个问题的最好方法是什么


谢谢。

在普通SQL中,您应该使用左外连接。这将保留出现在左侧表(首先列出的表)中的行,即使右侧表(列出的第二个表和外部联接的表)中没有匹配的行也是如此。对于右边表格中应该存在但不存在的值,结果是空值。因此,缺少价格的项目的价格将显示为空

在LINQ到SQL中的转换是另一回事


你可能会想一想,拥有没有价格的产品是否合理。您正在模拟一种称为-实体、属性、值-表的东西,它们通常被认为是“不好的东西”。

您不能只进行简单的连接吗

var乘积= 从p到db.乘积 在p.id上的db.ProductSpecs中加入ps等于ps.product\u id 其中ps.spec_name==“价格” orderby ps.spec_值
选择p

首先,我建议您在纯SQL中以函数或存储过程的形式执行此操作,然后通过linq访问此操作,或者在产品表中添加价格列。似乎价格将是添加到所有产品的正常属性,即使该价格为空

SQL:

话虽如此,这里有一点奇怪的LINQ应该在您的表中工作(我可能有一些列名拼写错误):

我在一些类似上面设置的表上测试了这一点,创建了5个产品,其中3个具有不同价值顺序的价格,这个LINQ像上面的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
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;