Построение динамического оператора where, Linq To Sql - PullRequest
3 голосов
/ 17 декабря 2011

Сначала я использую EF Code 4.2, Какое решение вы предлагаете, когда предложение where необходимо динамически построить? Тем не менее, функциональность Включить будет крайне необходима:

var results = db.Set<dynamicType>.Where("dynamic conditions").Include("....");

Приведенное выше динамическое условие требует поиска в другой таблице для фильтрации записей: Если бы я хотел написать это в выражении Linq, это было бы что-то вроде:

var result = db.Set<Contact>().Where(c=>c.AccountId == _Id_param || db.Set<LinkTable>().Any(a=>a.FkFieldId == c.AccountId && a.ParentId == _Id_param)).Include("Quotes");

Мне в основном нужен динамический linq вышеприведенного выражения, поскольку для разных типов изменяются поля условия Where (контакт - только пример), например, в одной модели поле FK может быть «AccountId», а в другой - быть "AccountFKId". Так что предложение Where должно быть динамическим!

Ответы [ 2 ]

3 голосов
/ 17 декабря 2011

IQueryable является составной, поэтому вы можете создавать запросы на лету:

var query = db.Set<Contact>().Include(...);

if (something) 
{
    query = query.Where(...);
}

// Other wheres

Linq строго типизирован, поэтому вы всегда должны знать, с какого типа вы собираетесь начать свой вызов Set<>. Вы можете сделать его универсальным, но не динамическим (если вы не собираетесь писать его целиком посредством размышлений).

Вы можете использовать dynamic linq , чтобы определить, где условия со строками, но опять же вам, по крайней мере, нужно будет знать тип для Set<>.

1 голос
/ 17 декабря 2011

ОБНОВЛЕНИЕ

Мне удалось решить проблему с помощью непосредственного изменения дерева выражений.

Использование идеи из Блога ТомасП помоглоlot:

Ключ был в том, чтобы создать второй IQueryable для внутреннего запроса и затем передать его в качестве выражения в выражение IQueryable существующей динамической модели.

IQueryable<LinkTable> linkQuery = db.Set<LinkTable>().AsQueryable();

MethodCallExpression internalQueryWhere = Expression.Call(typeof(Queryable), "Where", new Type[] { linkQuery.ElementType }, linkQuery.Expression,Expression.Lambda<Func<LinkTable, bool>>(myfilters, new ParameterExpression[] { filterParameter })); 

linkQuery = linkQuery.Provider.CreateQuery<LinkTable>(internalQueryWhere);

Expression anyMethodExpr = Expression.Call(typeof(Queryable), "Any", new Type[] { linkQuery.ElementType }, linkQuery.Expression);

Теперь вы можете передать anyMethodExprк предложению IQueryable где исходное юридическое лицо.

...