Указанный член типа не поддерживается в LINQ to Entities. Поддерживаются только инициализаторы, сущности и свойства навигации сущности
var result =
(from bd in context.tblBasicDetails
from pd in context.tblPersonalDetails.Where(x => x.UserId == bd.UserId).DefaultIfEmpty()
from opd in context.tblOtherPersonalDetails.Where(x => x.UserId == bd.UserId).DefaultIfEmpty()
select new clsProfileDate()
{
DOB = pd.DOB
});
foreach (clsProfileDate prod in result)
{
prod.dtDOB = !string.IsNullOrEmpty(prod.DOB) ? Convert.ToDateTime(prod.DOB) : DateTime.Today;
int now = int.Parse(DateTime.Today.ToString("yyyyMMdd"));
int dob = int.Parse(prod.dtDOB.ToString("yyyyMMdd"));
string dif = (now - dob).ToString();
string age = "0";
if (dif.Length > 4)
age = dif.Substring(0, dif.Length - 4);
prod.Age = Convert.ToInt32(age);
}
GetFinalResult(result);
protected void GetFinalResult(IQueryable<clsProfileDate> result)
{
int from;
bool bfrom = Int32.TryParse(ddlAgeFrom.SelectedValue, out from);
int to;
bool bto = Int32.TryParse(ddlAgeTo.SelectedValue, out to);
result = result.AsQueryable().Where(p => p.Age >= from);
}
Здесь я получаю исключение:
Указанный член типа "Возраст" не поддерживается в LINQ to Entities. Только инициализаторы, сущности и свойства навигации сущности поддерживаются.
Где Age нет в базе данных, это свойство, которое я создал в классе clsProfileDate для вычисления Age from DOB. Любое решение для этого?
Ответы
Ответ 1
Вы не можете использовать свойства, которые не сопоставлены столбцу базы данных в выражении Where
. Вы должны создать выражение на основе отображаемых свойств, например:
var date = DateTime.Now.AddYears(-from);
result = result.Where(p => date >= p.DOB);
// you don't need `AsQueryable()` here because result is an `IQueryable` anyway
В качестве замены вашего не отображаемого свойства Age
вы можете извлечь это выражение в статический метод:
public class clsProfileDate
{
// ...
public DateTime DOB { get; set; } // property mapped to DB table column
public static Expression<Func<clsProfileDate, bool>> IsOlderThan(int age)
{
var date = DateTime.Now.AddYears(-age);
return p => date >= p.DOB;
}
}
И затем используйте его следующим образом:
result = result.Where(clsProfileDate.IsOlderThan(from));
Ответ 2
Многие люди собираются сказать, что это плохой ответ, потому что это не лучшая практика, но вы также можете преобразовать его в список до своего места.
result = result.ToList().Where(p => date >= p.DOB);
Ответ Slauma лучше, но это тоже сработает. Это стоит больше, потому что ToList() выполнит запрос по базе данных и перенесет результаты в память.
Ответ 3
Вы также получите это сообщение об ошибке, когда вы случайно забыли определить сеттер для свойства.
Например:
public class Building
{
public string Description { get; }
}
var query =
from building in context.Buildings
select new
{
Desc = building.Description
};
int count = query.ToList();
Вызов ToList вызовет такое же сообщение об ошибке. Это очень тонкая ошибка и очень трудно обнаружить.
Ответ 4
Я забыл выбрать столбец (или установить/сопоставить свойство со значением столбца):
IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
where ...
select new DataModel { Name = t.Name };
Вызов queryable.OrderBy("Id")
вызовет исключение, даже если для DataModel
определено свойство Id
.
Правильный запрос:
IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
where ...
select new DataModel { Name = t.Name, Id = t.Id };
Ответ 5
В этом случае один из самых простых и лучших подходов - сначала привести его к list
, а затем использовать where
или select
.
result = result.ToList().where(p => date >= p.DOB);
Ответ 6
Проверка Count() перед предложением WHERE решила мою проблему. Это дешевле, чем ToList()
if (authUserList != null && _list.Count() > 0)
_list = _list.Where(l => authUserList.Contains(l.CreateUserId));