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;