6

データベース モデルの上にモデルがあり、オブジェクトをリポジトリにマップします。

ただし、GetUsers で直接「新規を選択」するか、以下に実装するように「factoryresult を選択」するかは明らかに違いがあります。実行時に、メソッド CreateFromDbModel に sql への変換がないというエラーが表示されます (System.NotSupportedException)。

これを回避する方法はありますか?どうにか直すことはできますか?

ファクトリ メソッドを使用する理由は、オブジェクトを別の場所でインスタンス化し、「マッピング コード」を 1 か所に保持したいからです...

コメントありがとう、アンダース

    public IQueryable<User> GetUsers(bool includeTeams)
    {
        return from u in _db.sc_Players
               where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam))
               select UserFactory2.CreateFromDbModel(u);
    }


    public static User CreateFromDbModel(sc_Player player)
    {
        return new User
                   {
                       Id = player.sc_PlayerID,
                       FirstName = player.FirstName.Trim(),
                       LastName = player.LastName.Trim(),
                       PresentationName = player.FirstName.Trim() + " " + player.LastName.Trim(),
                       LoginName = player.aspnet_User.LoweredUserName,
                       IsTeam = player.IsTeam,
                       Email = player.aspnet_User.aspnet_Membership.Email,
                       Password = player.aspnet_User.aspnet_Membership.Password
                   };
    }
4

2 に答える 2

1

エラーはそれをすべて説明しています。

「メソッドCreateFromDbModelにはSQLへの変換がありません(System.NotSupportedException)」

CreateFromDbModel メソッドは SQL 関数ではありません。オブジェクトがサーバーから明確に返されるまで、アプリケーションは CreateFromDbModel 関数を実行できません。クエリで CreateFromDbModel を実行する前に、クエリで ToList() などを呼び出す必要がある可能性が高くなります。

于 2009-09-10T04:59:22.887 に答える
1

GetUsers メソッドで IQueryable を返していることが問題ですか? 代わりに List を返してみてください。これにより、Linq クエリがメソッド内で強制的に実行されます。

public List<User> GetUsers(bool includeTeams)
{
    return (from u in _db.sc_Players
    where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam))
    select UserFactory2.CreateFromDbModel(u)).ToList();
}

これで問題が解決するかどうかはわかりませんが、ただの予感です。Linqpad で行っていることをローカル データベースに複製することができましたが、うまくいきました。しかし、私のサンプルは IQueryable を返していませんでした。GetUsers() の外で IQueryable コレクションをさらに変更していますか?

編集:

さらにチェックを行いました。GetUsers() を呼び出した後、IQueryable コレクションが 2 番目の Linq クエリで使用されるようにサンプルを変更した場合にのみ、エラーを再現できました。

IQueryable<User> query = GetUsers(true);

var q = from u in query
    where u.Name.Contains("Bob")
    select new {Name = u.FirstName + " " + u.LastName};

GetUsers() で上記のように List を返せば、エラーはなくなるはずです。唯一の欠点は、.ToList() を呼び出すときに既にクエリを実行しているため、GetUsers() を呼び出した後に行うフィルタリングでは、データベースから返されるデータの量が制限されないことです。

編集2:

残念ながら、ファクトリ メソッドをクエリに含める方法は他にないと思います。もう1つアイデアがあります。IQueryable の拡張メソッドを作成して、ToUserList() のように呼び出すことができます。ToUserList() 内では、クエリで ToList() を呼び出し、ユーザーのコレクションを返すファクトリ メソッドを呼び出します。Linq を使用してデータのフィルター処理が完了したら、このメソッドを呼び出します。これにより、データベースからデータをロードする準備ができたときにのみクエリを実行できます。以下に例を示します。

public static List<Users> ToUserList(this IQueryable<User> query)
{
     return query.ToList().Select(u => UserFactory2.CreateFromDbModel(u)); 
}

次のように拡張メソッドを呼び出します。

// Filter the data using linq. When you are ready to execute the query call:
query.ToUserList(); // Query will execute and a list of User objects returned.

これが理にかなっていることを願っています。ダグラス H.

于 2009-09-10T04:50:54.680 に答える