C # Динамическое предложение WHERE в LINQ to SQL Query - PullRequest
3 голосов
/ 20 августа 2009

Я хотел бы выполнить запрос LINQ с динамическим предложением where в зависимости от того, сколько различных вариантов пользователь ввел для своих критериев.

Возможно ли это?

Я разместил код ниже, как я хотел бы, чтобы он работал.

Кто-нибудь получил какие-либо предложения?

P.S. Я попытался использовать метод .Contains (генерирование WHERE IN в SQL, однако число параметров превысило пороговое значение 2100 и вызвало ошибку "LINQ Неверный поток протокола вызова RPC для потока табличных данных (TDS) . Слишком много параметров было предоставлено в этом запросе RPC. Максимум 2100 ".


private struct ProductStruct
        {
            public long ProductID;
        }

        private struct FilterStruct
        {
            public long ProductTypeFieldID;
            public long ValueNumber;
        }

List filterList = new List();
filterList.Add(new FilterStruct { ProductTypeFieldID = 3, ValueNumber = 195 });
filterList.Add(new FilterStruct { ProductTypeFieldID = 8, ValueNumber = 55 });

List productList = new List();

productList = (from pfv in dC.ProductFieldValues
                           where
                                foreach (FilterStruct filter in filterList)
                                {
                                    pfv.ProductTypeFieldID == filter.ProductTypeFieldID
                                    && pfv.ValueNumber == filter.ValueNumber
                                }
                           select new ProductStruct
                           {
                               ProductID = pfv.ProductID
                           }).ToList();

EDIT

Это выглядит так, как будто это может быть удобно, но не работает с динамикой где в?

<code>

 private void Option2()
        {
            try
            {
                LinqDataDataContext dataConnection = new LinqDataDataContext(ConnectionString);

                List filterList = new List();
                    filterList.Add(new FilterStruct { ProductTypeFieldID = 3, ValueNumber = 195 });
                    filterList.Add(new FilterStruct { ProductTypeFieldID = 8, ValueNumber = 55 });

                string whereClause = null;
                foreach (FilterStruct filter in filterList)
                {
                    if (whereClause != null)
                        whereClause += "AND ";

                    whereClause += string.Format("ProductID IN (SELECT ProductID FROM ProductFieldValue WHERE ProductTypeFieldID = {0} AND ValueNumber = {1})", filter.ProductTypeFieldID, filter.ValueNumber);

                }


                List productList = new List();
                    productList = (from pfv in dataConnection.ProductFieldValues.Where(whereClause)
                                    select new ProductStruct
                                          {
                                          ProductID = pfv.ProductID
                                          }).ToList();

            } 
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

        }


thanks in advance

Ответы [ 4 ]

4 голосов
/ 20 августа 2009

Из принятого ответа: Как динамически создать LINQ

Это хорошо работает для классов .AsQueryable (), но классы .Enumerable () можно использовать, если вы используете «as iQueryable ()»

linq using string as where statement

0 голосов
/ 20 августа 2009

Ответ, который я получил на похожий вопрос, работал для меня:

Как добавить динамические предложения where в запрос linq?

(Ответ был использован Predicate Builder )

0 голосов
/ 20 августа 2009

Вот простой пример использования IQueryable в VB.

Private Function GetZeroScoreWhere(ByVal qry As IQueryable(Of ScoreTest), ByVal score As ScoreTest) As IQueryable(Of ScoreTest)
    If score.CallType = ScoreTest.CallTypeEnum.XXX Then
        Return qry.Where(Function(c) c.AvgScore.Value = 0 Or c.Zero.Trim <> String.Empty)
    End If

    Return qry.Where(Function(c) c.ValidScore.Value = 0)
End Function

Тот же код в C #:

private IQueryable<ScoreTest> GetZeroScoreWhere(IQueryable<ScoreTest> qry, ScoreTest score)
{
    if(score.CallType == ScoreTest.CallTypeEnum.XXX)
    {
        Return qry.Where(c => c.AvgScore.Value == 0 || c.Zero.Trim != String.Empty)
    }

    Return qry.Where(c => c.ValidScore.Value == 0)    
}
0 голосов
/ 20 августа 2009

Вы можете использовать предложение JOIN:

from pfv in dC.ProductFieldValues
join filter in filterList on (
    pfv.ProductTypeFieldID == filter.ProductTypeFieldID 
    && pfv.ValueNumber == filter.ValueNumber
)
select new ProductStruct                           
{                               
    ProductID = pfv.ProductID                           
}
...