2016-07-21 13 views
0

DataResponseというクラスを作成しましたが、これには40以上のパブリックフィールドがあります。クラスDataResponseは、私のデータベースDataRepoesのものと同じ数のフィールドとタイプを持っています(これを前提としましょう)。c#各フィールドを経由せずにカスタムオブジェクトのコレクションを作成するには

私はオブジェクトのリストを作成し、自動的にフィールドがDataResponseに割り当てられているDBの内容からlinqのようなことをする方法はありますか?それ以外の場合は、DataResponseクラスを新規作成するときに、40個の各フィールドをそれぞれスペルアウトして手動で割り当てる必要があります。ありがとう

+2

たぶん[AutoMapper](http://automapper.org/)? –

答えて

1

あなたはAutoMapperが提供する柔軟性を必要としないか、サードパーティのライブラリを使用したくない場合は、以下の単純化されたカスタム拡張メソッドを使用することができますが:

public static class QueryableExtensions 
{ 
    public static IQueryable<TResult> SelectTo<TResult>(this IQueryable source) 
    { 
     var sourceType = source.ElementType; 
     var resultType = typeof(TResult); 
     var parameter = Expression.Parameter(sourceType, "x"); 
     var bindings = 
      from rm in resultType.GetProperties().Concat<MemberInfo>(resultType.GetFields()) 
      join sm in sourceType.GetProperties().Concat<MemberInfo>(sourceType.GetFields()) 
       on rm.Name equals sm.Name 
      select Expression.Bind(rm, Expression.MakeMemberAccess(parameter, sm)); 
     var body = Expression.MemberInit(Expression.New(resultType), bindings); 
     return source.Provider.CreateQuery<TResult>(Expression.Call(
      typeof(Queryable), "Select", new[] { sourceType, resultType }, 
      source.Expression, Expression.Quote(Expression.Lambda(body, parameter)))); 
    } 
} 

これは、すべてを選択しようとします名前で一致するプロパティ/フィールド。一致するプロパティ/フィールドタイプが異なる場合は失敗します。

使用例:

メソッドの構文

var res = con.DataRepoes 
    .Where(rx => iaccess.Contains(rx.STOREID)) 
    .SelectTo<Classes.DataResponse>() 
    .ToList(); 

クエリ構文

var res = 
    (from rx in con.DataRepoes 
    where iaccess.Contains(rx.STOREID) 
    select rx) 
    .SelectTo<Classes.DataResponse>() 
    .ToList(); 
+0

ありがとうございます。はい、私は第三者libを使用しない方がセキュリティレビューを経なければならないので好きです。私はこれを試してみましょう。 – Zuzlx

+0

ありがとうIvan。泣いている赤ん坊の子守歌のように働いた。あなたのコードを見て、私に魚の釣り方を教えてくれれば、次の愚か者(私のような)のためには素晴らしいだろう。私は 'on rm.Name equals sm.Name'と同じになるまでそれを理解しています。 – Zuzlx

+0

Lol、ソースプロパティ/フィールドをターゲットプロパティ/フィールドに名前でマッピングする方法はLINQです - [join](https://msdn.microsoft.com/en-us/library/bb311040.aspx)を参照してください。喜んで助けて、幸せなコーディング:) –

2

オートマッテQueryable Extensionsを使用できます。 Classes.DataResponse内のフィールドを想定し

DataRepoesでのものと同じ名前を持っているあなたは、その後、行うことができます。

// During your application bootstrap, configure AutoMapper to create a map between the two types 
Mapper.Initialize(cfg => cfg.CreateMap<DataRepoes, Classes.DataResponse); 


// Then you can ask AutoMapper to project the IQueryable directly to your DTO 
List<Classes.DataResponse> res = con.DataRepoes 
            .Where(rx => iaccess.Contains(rx.STOREID)) 
            .ProjectTo<Classes.DataResponse>() 
            .ToList();          
1

これは、LINQを使用して可能ではありません。 しかし、これを達成するには "AutoMapper"を使用できます。 ただ、CreateMapこれら二つのクラスのために、その後に役立ちますそれら

Mapper.CreateMap<DataResponse,DataRepo>();//Assuming DataRepoes is collection of DataRepo types 
List<Classes.DataResponse> res = (from rx in con.DataRepoes 
            where iaccess.Contains(rx.STOREID) 
            select Mapper.Map<Classes.DataResponse>(rx)). 
            ToList<Classes.DataResponse>(); 

・ホープの地図!

関連する問題