質問

LINQオブジェクトをLINQデータプロバイダーに保持し、フィルタリングなどを許可するためにIQueryableを返す際に、他のユーザーと同様のアプローチを使用しています。他の子オブジェクトで構成される結合テーブルオブジェクトの問題

    //CoreDBDataContext db = coreDB;
public IQueryable<DTO.Position> GetPositions()    {
     return from p in coreDB.Positions
         select new DTO.Position
             {
             DTO.User = new DTO.User(p.User.id,p.User.username, p.User.firstName,p.User.lastName,p.User.email,p.User.isActive),
             DTO.Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
             DTO.OrgUnit = new DTO.OrgUnit(p.OrgUnit.id,p.OrgUnit.name,p.OrgUnit.isActive)
             };

coreDB.Positionsは私のLinq Positionオブジェクトであり、User、OrgUnit、およびRoleで構成されるDTO Positionを返します(基になるテーブルはUserID、RoleID、およびOrgUnitIDを持つ結合テーブルです)

私が抱えている問題は、Iqueryableにフィルターを追加しようとすると、DTO.Userオブジェクトの翻訳が利用できないというSQLエラーが表示されることです

public static IQueryable<Position> WithUserID(this IQueryable<Position> query, int userID)
    {
        return query.Where(p => p.User.ID == userID);
    }

すべてのGoogleの結果は、生成されたLINQオブジェクトを直接操作している人のものであると思われるため、これを解決する方法について完全に迷っています

この作業を行う方法について何か考えましたか、またはここで完全に間違ったことをしていますか?

ありがとう

役に立ちましたか?

解決 3

複雑なクエリにフィルターを使用しないことになりました。代わりに、より複雑なクエリ要件のために、リポジトリにメソッドを追加しました。これにより、システムが理解しやすくなり、保守が容易になります。

他のヒント

同様のアプローチで問題なく作業できました:

var courses = from c in Map(origCourses)
where !expiredStatuses.Contains(c.Status)
select c;

マップの場所:

    select new UserCourseListItem
    {
        CourseID = c.CourseID,
        CourseName = cm.CourseName,
        CourseType = c.CourseType.Value
        ...

(コンストラクタではなく)そのタイプの初期化で試してみてください。

これは動作しているアプリケーションの一部であり、expiredStatusesは複雑な式に関連しています。

更新1:これは、前述のシナリオと比較して類似しています。理由は次のとおりです。

  • マップは、POCOオブジェクトであるIQueryableを返します。
  • POCOオブジェクトでIQueryableを返すMapメソッドを呼び出した後、フィルターを適用しています。

Linq2SQLは、デザイナーが生成したオブジェクトのみを理解します。まあ、それは完全に真実ではありませんが、十分に近いです。

したがって、LinqクエリをLinq2SQLオブジェクトに対して再度記述すると、クエリは書き込まれたときではなく、実際に実行されたときに有効なSQLに変換されます。 DTOオブジェクトはLinq2SQLオブジェクトではないため、Linq2SQLは適切なSQLを作成する方法を知りません。

このように分離を維持する場合は、Linq2SQLオブジェクトのみを使用してクエリを実行し、結果をDTOにマップする方法を見つける必要があります。

クエリメソッドを次のように書き換えることができます:

  

更新:パラメーターはタイプである必要があります   Expression<>、およびする必要はありません   IQueryable<>を返します。おかげで   指摘してくれたフレディ。

public IEnumerable<DTO.Position> FindPositions(Expression<Func<Position, bool>> criteria)
{
    return from p in coreDB.Positions
           where criteria.Invoke(p)
           select new DTO.Position
                      {
                          User = new DTO.User(p.User.id, p.User.username, p.User.firstName, p.User.lastName,
                                       p.User.email, p.User.isActive),
                          Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
                          OrgUnit = new DTO.OrgUnit(p.OrgUnit.id, p.OrgUnit.name, p.OrgUnit.isActive)
                      };
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top