21

サードパーティが利用できるようになり、自分の Web アプリケーションでも使用される Web API プロジェクトを構築しています。Web API メソッドは、複合型/オブジェクトの JSON 表現を返します。これらは事前定義されたクラスであり、サードパーティが利用できるようにして、データがどのように構造化されているかを理解し、JSON を逆シリアル化できるようにします。誰かが訂正してくれるまで、これらのクラスを DTO クラスと呼びます。

私は(データベースから)次の自動生成されたエンティティモデルを持っていますが、これはとにかくスキャンテーブルとの関係を持つユーザークラスです(この質問の目的のために関係は無視できます)...

public partial class User
{
    public User()
    {
        this.Scans = new HashSet<Scan>();
    }

    public int Id { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public bool Active { get; set; }

    public virtual ICollection<Scan> Scans { get; set; }
}

そして、List としてプレゼンテーション層に戻したい次の DTO クラス (ビジネスからプレゼンテーションに IEnumerable を使用する必要はないと思いますか?)。

public class User
{
    public int Id;
    public string Username;
    public string Password;
    public bool Active;
}

このコンポーネントのビジネス レイヤーは現在、以下のようになっています。Linq を使用してデータベースからユーザーを取得し、結果を解析して POCO ユーザーの List<> を返します。

public List<User> Get()
{
    List<User> userList = new List<User>();

    using (var db = new MyContext())
    {
        var query = from u in db.Users
                    orderby u.FirstName
                    select u;

        foreach (var item in query)
        {
            User user = new User();
            user.Id = item.pkUser;
            user.Username = item.Username;
            user.Password = item.Password;
            user.Active = item.Active;

            userList.Add(user);
        }
    }

    return userList;
}

このような結果の解析は非効率に思えますが、Linq クエリでこの種のことを繰り返しなしで実行できることがわかりました (たとえば、この質問の回答Linq Query results to a DTO class )。

オブジェクトでこのタイプの Linq クエリを有効にするために IEnumerable を実装する場所/方法がわかりません。また、上記の参照された質問と同様のクエリを作成する方法もわかりませんが、より単純なシナリオです。

助けてくれてありがとう。

PS Web API を介してユーザー名とパスワードを公開しているという事実と、すべてのユーザーを一度に返しているという事実を無視してください。上記は、この質問のために私のコードを簡略化したものです。

4

4 に答える 4

37

完全な方法は次のとおりです。

public List<User> Get()
{
    using (var db = new MyContext())
    {
        return (from u in db.Users
                orderby u.FirstName
                select new User()
                {
                    Id = u.pkUser,
                    Username = u.Username,
                    Password = u.Password,
                    Active = u.Active
                }).ToList();
    }
}

「反復なし」の結果が必要だと言いました。LINQ を使用しても、繰り返しがなくなるわけではありません。コードでは実行していませんが、ToList()メソッドを呼び出すと実際に発生します。

于 2013-02-28T00:00:17.580 に答える
9

LINQ to Objects を使用して変換を行うことができます。

using (var db = new MyContext())
{
    var query = from u in db.Users
                orderby u.FirstName
                select u;

    return query.AsEnumerable().Select(item => 
                 new User 
                     { 
                        Id = item.pkUser,
                        Username = item.Username,
                        Password = item.Password,
                        Active = item.Active
                     }).ToList();
}
于 2013-02-27T23:58:48.967 に答える
2

AutoMapperを使用すると、非常にコンパクトになります。

リポジトリでマッパーをブートストラップします。

Mapper.CreateMap<AutoGenNamespace.User, DtoNamespace.User>();

次に、それは非常に簡単です (IEnumerable を返すことに問題はありません)。

public IEnumerable<User> Get()
{
    using (var db = new MyContext())
    {
        return (from u in db.Users
                orderby u.FirstName
                select Mapper.Map(u)).AsEnumerable();
    }
}
于 2013-02-28T00:07:47.770 に答える
-1

私のクエリには、複数の子を持つ親テーブルがあります。

public class TeamWithMembers
        {
            public int TeamId { get; set; }
            public string TeamName { get; set; }
            public string TeamDescription { get; set; }
            public List<TeamMembers> TeamMembers { get; set; }
        }

これToList()で、linqクエリでを使用していたときにエラーが発生しました。今、私はlinqクエリで匿名型を使用しており、次のような次のクエリに変換しています

List<TeamModel.TeamWithMembers> teamMemberList = teamMemberQueryResult.AsEnumerable().Select(item =>
new TeamModel.TeamWithMembers() {
    TeamId=item.TeamId,
    TeamName=item.TeamName,
    TeamMembers=item.TeamMembers.ToList()
}).ToList();

teamMemberQueryResultlinq クエリの結果セットはどこにありますか。

于 2016-01-13T00:57:28.450 に答える