还有另一种方法来执行此查询吗? (包含linq-to-sql查询中的拆分字符串)

时间:2011-07-06 13:53:19

标签: c# linq linq-to-sql

我有一个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(); 
    }

还有另一种方法来编程吗?

4 个答案:

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