私はこのトピックに関する多くの質問を見てきましたが、私が見ている問題を実際に解決する質問を選別することはできませんでした。どの従業員が割り当てられているか、どの従業員がレコードを作成して更新したかを追跡するアクティビティエンティティがあります。 「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>
..........
私の推測では、エラーは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());
オブジェクト全体の平等をデータベースクエリに変換しようとしているという事実は好ましくありません。 SQLクエリのように、定数値を使用してのみエンティティフレームワーククエリを実行できます。これを解決するには、IDを比較して、AssignedEmployeeのIDが従業員テーブルの現在のユーザーのIDと同じかどうかを確認します。
追記として、追跡しているcurrentUser
オブジェクトがEmployeeタイプではない場合、後のクエリで参照できるように、そのユーザーの対応するEmployeeレコードをキャッシュすることを検討してください。それはそのテーブルを絶えず通過しようとするよりもずっと良いでしょう。 (繰り返しますが、実際には別のテーブルにある場合にのみ影響します)
==と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式に変換する必要がありますであることを忘れないでください。これは、結局のところ、データベースを呼び出し、メモリからのものにアクセスしないためです。