Linq to SQL, как сделать «где [столбец] в (список значений)»

У меня есть функция, в которой я получаю список идентификаторов, и мне нужно вернуть список, соответствующий описанию, связанному с идентификатором. Например:.

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?

85 голосов | спросил Nathan 2 J000000Thursday09 2009, 20:59:58

4 ответа


0

Использование

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));
ответил Jon Skeet 2 J000000Thursday09 2009, 21:04:07
0

Вы также можете использовать:

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;
ответил Nick DeMayo 2 J000000Thursday09 2009, 21:18:25
0

Я использовал этот метод в ответе Джона Скита, но другой мне пришло в голову использование 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% быстрее, хотя один раз ---- +: = 7 =: + ---- метод, выигранный просто smidgen.

ответил DCShannon 18 +04002014-10-18T05:48:46+04:00312014bEurope/MoscowSat, 18 Oct 2014 05:48:46 +0400 2014, 05:48:46
0
 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();
ответил Deepan Raj 29 PM00000020000002631 2015, 14:55:26

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132