Как следует из наглядности, вам нужно использовать выражение Func вместо прямого Func:
public Expression<Func<T, bool>> GetLmbLang<T>() where T:class,IBaseGenericTxt
{
int lang = -1;
lang = Convert.ToInt32(HttpContext.Current.Session["Language"]);
return (p => p.LangID == lang);
}
Edit
Ах, да, хорошопроблема в том, что ваша функция на самом деле не знает, с каким классом она работает во время компиляции: она знает только, что это класс, и реализует IBaseGenericTxt.Поэтому, когда вы говорите p.LangId
, эта часть выражения вызывает IBaseGenericTxt.LangId, а не ContactTypeText.LangId.
Вам нужно будет создать собственное дерево выражений, чтобы это работало правильно.Примерно так:
var paramExpr = Expression.Parameter(typeof(T), "p");
return Expression.Lambda<Func<T, bool>>(
Expression.Equal(
Expression.Property(paramExpr, "LangId"),
Expression.Constant(lang)),
paramExpr);
Изменить 2
Две вещи:
- Поскольку LINQ to Entities будет пытаться принять что-либо вВыражение запроса и преобразование его в оператор SQL, вы должны быть осторожны, чтобы не вызывать методы в середине вашего запроса.Сначала вам нужно вызвать метод GetLmbLang и сохранить его значение в переменной для использования в запросе.
Как вы указали в своем комментарии, поскольку свойство ContactTypeTexts не реализует IQueryable, этостановится особенно сложно.Насколько я могу судить, у вас есть три варианта:
- Создайте весь оператор выбора в виде дерева выражений.Это очень раздражает и подвержено ошибкам.
- Используйте LinqKit Джо Альбари для «компиляции» и «расширения» вашего запроса.LinqKit будет проходить по дереву выражений и строить новое дерево, в котором выражение запроса будет преобразовано в эквивалентный ему Func.
- Вернитесь к контексту данных, а не используйте свойство ContactTypeTexts.
Лично я бы, наверное, выбрал последний вариант, например:
var lambdaLang = repGeneric.GetLmbLang<ContactTypeText>();
var ViewModel = _db.Contacts
.Where(a=> a.IsActive == true)
.Select(a => new ContactListViewModel {
ContactID = a.ContactID,
ContactName = a.ContactName,
Role = _db.ContactTypeTexts
.Where(ct => ct.ContactType.Contacts.Any(
c => c.ContactId == a.ContactId)
.Where(lambdaLang)
.Select(af => af.Txt).FirstOrDefault(),
CompanyType = a.Supplier.SupplierName,
Addr = a.Address ,
Email = a.ContactEmail,
Phone = a.ContactPhone
}).ToList();