我有一个sql数据库,其中包含一些包含某些产品的表,每个产品都可以在一台或多台机器上生成。现在我想搜索在某台机器上生产的所有产品。
表是这样的:
productreference(nvarchar)|机器(为nvarchar)
P1 | 1,2,3
P2 | 2
P3 | 2
P4 | 2,3
我尝试使用以下查询,但我发现linq-to-sql不支持拆分字符串。
public List<string> GetReferenceForMach(string machName)
{
IEnumerable<string> producttmp = from product in productInfo
let machines = product.Machines.Split(',')
from machine in machines
where machine == machName
select product.Reference;
return producttmp.ToList();
}
还有另一种方法来编程吗?
答案 0 :(得分:3)
当life在数据库中为您提供字符串时,正常的响应是使用字符串解析:
string machName;
string midName = ',' + machName + ',';
from product in productInfo
where (',' + product.Machines + ',').Contains(midName)
select product.Reference
没有索引可以帮助这个查询 - 所以支持表扫描。
答案 1 :(得分:1)
Linq to SQL good 但不是魔法!它仍然必须将您的查询减少到可执行SQL(这就是为什么不允许string.Split
之类的函数 - 它们使得生成等效的SQL变得困难)。在这种情况下,您要求SQL服务器无法完成的任务(基于逗号分隔字段的内容进行搜索)。
如果您希望此操作像我认为您期望的那样,那么您需要更改数据库架构,以便Machines
拥有自己的表,因此可以对其进行索引和查询。
或者你可以使用Linq to SQL获取整个表/结果集,然后使用旧的Linq to Objects来完成这项工作:
IEnumerable<string> producttmp = from product in productInfo.AsEnumerable()
let machines = product.Machines.Split(',')
from machine in machines
where machine == machName
select product.Reference;
(未经测试)
答案 2 :(得分:0)
尝试
return productInfo.AsEnumerable()
.Where(p => p.Machines.Split(',').Contains(machName))
.Select(p => p.Reference)
.ToList()
AsEnumerable()关闭整个表并减少对linq-to-objects的查询。这种方法的缺点显然是,如果你的桌子很大,它可能会非常低效。
答案 3 :(得分:0)
谢谢大家的帮助,
现在可以使用,我使用了以下代码:
IEnumerable<string> producttmp = from product in productInfo
let midName = "," + machName + ","
let checkMachines = "," + product.Machines + ","
where (checkMachines.IndexOf(midName) > -1)
select product.Reference;
return producttmp.ToList();