41

このトピックに関する多くの質問を見てきましたが、私が見ている問題を実際に解決する質問を整理することはできませんでした. どの従業員に割り当てられているか、またどの従業員がレコードを作成して更新したかを追跡するアクティビティ エンティティがあります。コードの「where a.AssignedEmployee == currentUser」行を削除すると、以下の実行時エラーは発生しません。

タイプ 'DataModels.Employee' の定数値を作成できません。このコンテキストでは、プリミティブ型または列挙型のみがサポートされています。

コントローラ

var query = from a in db.Activities
            where a.AssignedEmployee == currentUser
            where a.IsComplete == false
            orderby a.DueDate
            select a;
return View(query.ToList());

見る

@model IEnumerable<Data.DataModels.Activity>
..........
4

3 に答える 3

65

私の推測では、エラーは、EF が等価演算子Employeeを SQL に変換できないことを示していると思います (参照等価性またはオーバーライドされた演算子を想定しているかどうかに関係なく==)。Employeeクラスに一意の識別子があると仮定して、次を試してください。

var query = from a in db.Activities
            where a.AssignedEmployeeId == currentUser.Id
            where a.IsComplete == false
            orderby a.DueDate
            select a;
return View(query.ToList());
于 2013-03-04T21:24:14.630 に答える
8

オブジェクト全体の等価性をデータベースクエリに変換しようとしているという事実は好きではありません。SQL クエリを実行する場合と同様に、定数値を使用してエンティティ フレームワーク クエリのみを実行できます。これを解決する方法は、ID を比較して、AssignedEmployee の ID が従業員テーブル内の現在のユーザーの ID と同じかどうかを確認することです。

補足として、currentUser追跡しているオブジェクトが Employee タイプでない場合は、そのユーザーの対応する Employee レコードをキャッシュして、後のクエリでより適切に参照できるようにすることを検討してください。それは、そのテーブルを常に調べようとするよりもはるかに優れています. (繰り返しますが、これは、実際には別のテーブルにある場合にのみ影響します)

于 2013-03-04T21:24:42.067 に答える
5

== と obj.Equals を使用する際の問題は、Entity Framework がそのメソッド呼び出しを SQL に変換する方法を認識していないことです。これら 2 つのメソッドを SQL に変換できるものにオーバーロードしたとしてもです。Entity Framework でこの欠点を修正するためにできることは、実行したいより複雑な等価チェックを行う式ツリーを返すメソッドを作成することです。

たとえば、次のクラスがあるとします。

public class Person {
    public string Firstname { get; set; } 
    public string Lastname  { get; set; }
}

Entity Framework が理解できるカスタムの等価演算を返すには、次のメソッドを Person クラスに追加します。

public static Expression<Func<Person, bool>> EqualsExpressionTree(  Person rhs )
{
    return ( lhs ) => string.Equals( lhs.Firstname, rhs.Firstname ) &&
                      string.Equals( lhs.Lastname, rhs.Lastname );
}

LINQ クエリでは、次のようにカスタム等値コードを活用できます。

Person anotherPerson = new Person { Firstname = "John", Lastname = "Doe" }
personCont.Where( Person.EqualsExpressionTree(anotherPerson) );
//...
if ( personCont.Any( Person.EqualsExpressionTree(anotherPerson)) ) {
//...

さらに、EqualsExpressionTree メソッドを書き直して静的な Equals メソッドを呼び出すことができるため、独自の等価ロジックを活用できます。ただし、結局のところ、コードは SQL 式に変換する必要があることを忘れないでください。結局のところ、データベースを呼び出しているのであって、メモリから何かにアクセスしているわけではないからです。

于 2014-05-30T05:31:52.673 に答える