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?

525   4  

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

    Ничего не найдено.