78
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);
}

ここで私は例外を取得しています:

指定されたタイプメンバー「Age」は、LINQtoEntitiesではサポートされていません。初期化子、エンティティメンバー、およびエンティティナビゲーションプロパティのみがサポートされます。

Ageがデータベースにない場合、DOBからAgeを計算するためにclsProfileDateクラスで作成したプロパティです。これに対する解決策はありますか?

4

7 に答える 7

108

式のデータベース列にマップされていないプロパティは使用できません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));
于 2012-07-21T11:55:54.610 に答える
23

多くの人は、これはベストプラクティスではないため、悪い答えだと言うでしょうが、場所の前にリストに変換することもできます。

result = result.ToList().Where(p => date >= p.DOB);

Slaumaの答えはより良いですが、これも同様に機能します。ToList()がデータベースに対してクエリを実行し、結果をメモリに移動するため、これにはさらにコストがかかります。

于 2013-04-16T16:12:17.553 に答える
17

プロパティのセッターを誤って定義し忘れた場合にも、このエラーメッセージが表示されます。例えば:

public class Building
{
    public string Description { get; }
}

var query = 
    from building in context.Buildings
    select new
    {
        Desc = building.Description
    };
int count = query.ToList();

ToListを呼び出すと、同じエラーメッセージが表示されます。これは非常に微妙なエラーであり、検出が非常に困難です。

于 2015-12-04T15:50:24.877 に答える
3

列を選択するのを忘れました(またはプロパティを列の値に設定/マップします):

IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
                                    where ...
                                    select new DataModel { Name = t.Name };

プロパティが定義されていても、呼び出しqueryable.OrderBy("Id")は例外をスローします。DataModelId

正しいクエリは次のとおりです。

IQueryable<SampleTable> queryable = from t in dbcontext.SampleTable
                                    where ...
                                    select new DataModel { Name = t.Name, Id = t.Id };
于 2018-07-17T14:48:12.123 に答える
3

私の場合、アプリケーションのバイナリが同一であっても、このエラーメッセージは本番環境でのみ表示され、ローカルで実行した場合には表示されませんでした。

私のアプリケーションでは、ランタイムで生成されたEDMXがディスクに保存され、起動時に(最初から再生成するのではなく)ディスクから読み込まれるようにカスタムを使用して、DbModelStoreアプリケーションの起動時間を短縮しています-コードのバグが原因でIディスク上のEDMXファイルを無効にしませんでした-そのため、Productionは、例外エラーメッセージでtype-nameの名前を変更する前の、アプリケーションのタイプの古いバージョンを参照するディスクのEDMXファイルの古いバージョンを使用していました。

キャッシュファイルを削除してアプリケーションを再起動すると修正されました。

于 2020-02-22T23:18:48.223 に答える
0

この場合、最も簡単で最良のアプローチの1つは、最初にキャストしてから、またはlistを使用することです。whereselect

result = result.ToList().where(p => date >= p.DOB);
于 2018-11-13T10:39:20.773 に答える
0

WHERE句の前にCount()をチェックすると、問題が解決しました。ToList()よりも安いです

if (authUserList != null && _list.Count() > 0)
    _list = _list.Where(l => authUserList.Contains(l.CreateUserId));
于 2019-09-23T07:39:58.117 に答える