Linq to SQL how to do " where [column] in (список значений)"
у меня есть функция, где я получаю список идентификаторов, и мне нужно вернуть список, соответствующий описанию, которое связано с идентификатором. Например:
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 для этого, я бы просто сделал что-то вроде следующего (где предложение in содержит все значения в аргументе 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;
проблема в том, что я не могу динамически генерировать список предложений "или" для linq to sql, потому что они задаются во время компиляции.
Как выполнить предложение where, которое проверяет столбец в динамическом списке значений с помощью Linq to Sql?
4 ответов:
использовать
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 ); }Тест Производительности
это не было даже отдаленно научным. Представляю вашему структура базы данных и количество идентификаторов, включенных в список, окажут значительное влияние.
Я создал тест, где я сделал 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();
Comments