我有一个函数在那里我得到ID列表,我需要返回一个匹配与该ID相关联的描述列表。 例如:
public class CodeData
{
string CodeId {get; set;}
string Description {get; set;}
}
public List<CodeData> GetCodeDescriptionList(List<string> codeIDs)
//Given the list of institution codes, return a list of CodeData
//having the given CodeIds
}
所以,如果我是为这个创建SQL我自己,我只想做类似如下(其中条款包含在codeIds参数中的所有值):
Select CodeId, Description FROM CodeTable WHERE CodeId IN ('1a','2b','3')
LINQ to SQL中我似乎无法找到“IN”子句的等价物。 最好我到目前为止(不工作)发现的是:
var foo = from codeData in channel.AsQueryable<CodeData>()
where codeData.CodeId == "1" || codeData.CodeId == "2"
select codeData;
问题是,我不能动态生成的“OR”子句的LINQ to SQL列表,因为它们是在编译时设置。
怎样才能完成,检查一列是使用LINQ to SQL值的动态列表where子句?
使用
where list.Contains(item.Property)
或者,你的情况:
var foo = from codeData in channel.AsQueryable<CodeData>()
where codeIDs.Contains(codeData.CodeId)
select codeData;
不过,你不妨做点标记:
var foo = channel.AsQueryable<CodeData>()
.Where(codeData => codeIDs.Contains(codeData.CodeId));
你也可以使用:
List<int> codes = new List<int>();
codes.add(1);
codes.add(2);
var foo = from codeData in channel.AsQueryable<CodeData>()
where codes.Any(code => codeData.CodeID.Equals(code))
select codeData;
使用乔恩斯基特的回答方法我了,可是另外一个使用发生在我身上Concat
。 该Concat
方法,在有限的测试稍好执行,但它是一个麻烦,我可能就坚持使用Contains
,或者也许我会写一个辅助方法为我做到这一点。 无论哪种方式,这里的另一种选择,如果有人有兴趣:
方法
// Given an array of id's
var ids = new Guid[] { ... };
// and a DataContext
var dc = new MyDataContext();
// start the queryable
var query = (
from thing in dc.Things
where thing.Id == ids[ 0 ]
select thing
);
// then, for each other id
for( var i = 1; i < ids.Count(); i++ ) {
// select that thing and concat to queryable
query.Concat(
from thing in dc.Things
where thing.Id == ids[ i ]
select thing
);
}
性能测试
这不是远程科学。 我想,你的数据库结构和参与名单将有显著影响ID的数量。
我设置了一个试验,其中我做的每100次试验Concat
和Contains
每个试验包括选择由主键的随机化的列表中指定的25行,其中。 我已经约了十几次跑这一点,最次Concat
方法出来的5 - 10%的速度,虽然一个时间Contains
的只是点点赢得方法。
var filterTransNos = (from so in db.SalesOrderDetails
where ItemDescription.Contains(ItemDescription)
select new { so.TransNo }).AsEnumerable();
listreceipt = listreceipt.Where(p => filterTransNos.Any(p2 => p2.TransNo == p.TransNo)).ToList();