动态Linq创建

时间:2011-08-01 15:46:42

标签: sql linq dynamic

我正在重写一个查询,该查询是为响应用户在文本字段中的输入而创建的,以便提供一些防止SQL注入攻击的保护。

SELECT DISTINCT (FileNameID) FROM SurNames WHERE Surname IN
('Jones','Smith','Armitage') 
AND FileNameID IN ( SELECT DISTINCT (FileNameID) FROM FirstNames WHERE FirstName 
IN ('John','William') )

此过程中最多可包含3个其他表。 参数列表最多可以包含50-100个条目,因此构建参数化查询既繁琐又繁琐。

我正在尝试创建一个Linq查询,它应该处理参数化并提供我需要的保护。

这给了我需要的东西

  var surnameValues = new[] { "Jones","Smith","Armitage" };
  var firstnameValues = new[] { "John","William" };

  var result = (from sn in db.Surnames
                from fn in db.FirstNames
                where surnameValues.Contains(sn.Surname) &&
                firstnameValues.Contains(fn.FirstName)
                select fn.FileNameID).Distinct().ToArray(); 

我现在需要一种动态创建方法,具体取决于用户是否在姓氏或名字文本输入框中选择/输入了值?

任何指针都会感激不尽

由于 罗杰

1 个答案:

答案 0 :(得分:1)

您可以将所有逻辑组合到查询中;

var surnameValues = new[] { "Jones","Smith","Armitage" };
var firstnameValues = null;

// Set these two variables to handle null values and use an empty array instead
var surnameCheck= surnameValues ?? new string[0];
var firstnameCheck= firstnameValus ?? new string[0];

var result = (from sn in db.Surnames
            from fn in db.FirstNames
            where
            (!surnameCheck.Any() || surnameCheck.Contains(sn.Surname)) &&
            (!firstnameCheck.Any() || firstnameCheck.Contains(fn.FirstName))
            select fn.FileNameID).Distinct().ToArray(); 

您的查询似乎没有Surnames表和firstNames表之间的连接条件?

您可以动态构建查询(因为您似乎在做我交叉加入我使用过SelectMany

var query=db.Surnames.SelectMany(sn=>db.FirstNames.Select (fn => new {fn=fn,sn=sn}));
if (surnameValues!=null && surnameValues.Any()) query=query.Where(x=>surnameValues.Contains(x.sn.Surname));
if (firstnameValues !=null && firstnameValues.Any()) query=query.Where(x=>firstnameValues.Contains(x.fn.FirstName));
var result=query.Select(x=>x.fn.FileNameID).Distinct();