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がデータベースにない場合、DOBからAgeを計算するためにclsProfileDateクラスで作成したプロパティです。これに対する解決策はありますか?
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));
多くの人がこれは悪い答えだと言うでしょう。なぜならそれはベストプラクティスではないが、あなたはそれをあなたの場所の前にリストに変換することもできるからです。
result = result.ToList().Where(p => date >= p.DOB);
Slaumaの答えは優れていますが、これも同様に機能します。 ToList()はデータベースに対してQueryを実行し、結果をメモリに移動するため、これにはさらにコストがかかります。
また、プロパティのセッターを誤って定義したことを忘れた場合にも、このエラーメッセージが表示されます。例えば:
public class Building
{
public string Description { get; }
}
var query =
from building in context.Buildings
select new
{
Desc = building.Description
};
int count = query.ToList();
ToListを呼び出すと、同じエラーメッセージが表示されます。これは非常に微妙なエラーであり、検出が非常に困難です。
列を選択するのを忘れました(または、プロパティを列の値に設定/マッピングします):
_IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
where ...
select new DataModel { Name = t.Name };
_
DataModel
にプロパティId
が定義されていても、queryable.OrderBy("Id")
を呼び出すと例外がスローされます。
正しいクエリは次のとおりです。
_IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
where ...
select new DataModel { Name = t.Name, Id = t.Id };
_
この場合、最も簡単で最良のアプローチの1つは、最初にlist
にキャストしてからwhere
またはselect
を使用することです。
result = result.ToList().where(p => date >= p.DOB);