2016-09-14 12 views
0

これは繰り返しの質問である場合はお詫び申し上げます。基本的に私が達成しようとしているのは、私の投影法が別のメソッド/クラスであり、これを再利用できるようにすることです(LINQの初心者です)。URIで指定されたクエリが有効でない+投影+ LINQ選択

public static Expression<Func<MyObject, object>> getProjection() 
    { 
     return r => new 
     { 
      Name = r.Name, 
      Address = r.Address, 
      City = r.City, 
      PostalCode = r.PostalCode, 
      Province = r.Province, 
      Country = r.Country, 
      Phone = r.Phone, 
      Website = r.Website 
     }; 
    } 

しかし、私はこのようにProjectionを呼び出します。

var filteredList = db.MyObject.Select(Projections.getProjection()).AsQueryable(); 
return Ok(filteredList); 

それから私は、エラー

は、URIで指定されたクエリが有効ではありません取得します。タイプ 'System.Object'で 'Name'という名前のプロパティ を見つけることができませんでした。

プロジェクションヘルパーメソッドをコピーして貼り付けだけで実際のプロジェクションに置き換えた場合、正常に機能します。私はちょうどヘルパーメソッド "getProjection"を作成して、他のSelectメソッドのために同じ投影を再び書き直さないようにしようとしています。まず、これがProjectionを呼び出す正しい方法であるかどうかを確認することができます。次に、そのODataエラーを取り除く方法を教えてください。

ありがとう

+0

オブジェクトではなく強く型付けされたアイテムを返す場合は、同じエラーが発生しますか?おそらくODataは動的オブジェクトについて混乱しているかもしれません。私の2番目の前提 - クエリの評価が必要な場合 - Select文の後にToList()を呼び出そうとしています(db.MyObject.Select(Projections.getProjection())ToList()。AsQueryable()) –

+0

@ n.piskunovありがとう返信のために。私は強く型付けを試みましたが、私はまだ同じエラーがあります。その後、私はあなたの2番目の提案を試みて、私は別のエラーが発生しました。下記参照。 === "エンティティまたは複合型 'Sample.DataContexts.MyObject'は、LINQ to Entitiesクエリで構築できません。"} – programmerboy

答えて

0

LINQは、強力なタイプを必要とします。それらは一般的なものでもよく、CANは匿名であってもよい。あなたの問題は、関数が弱い型の式を返すということです。

これを解決するには強いタイプを使用するか、投影方法を使用しないでください。

A:強いタイプです。これは実際には非常に整頓されており、と考えられます。怠惰ここで匿名タイプを試してみてください。

public class MyRecord { /* fields here */ } 
public static Expression<Func<MyObject, MyRecord>> getProjection() 
{ 
    return r => new MyRecord 
    { 
     Name = r.Name, 
     Address = r.Address, 
     City = r.City, 
     PostalCode = r.PostalCode, 
     Province = r.Province, 
     Country = r.Country, 
     Phone = r.Phone, 
     Website = r.Website 
    }; 
} 

/* of type IQueryable<MyRecord> */ 
var filteredList = db.MyObject.Select(getProjection()); 

B:あなたは別の方法にこれを返却する場合、あなたはまだ強い(非匿名)と入力が必要になるだろう、この

/* of type IQueryable<Anonymous> - this is why 'var' exists */ 
var filteredList = db.MyObject.Select(r => new 
{ 
    Name = r.Name, 
    Address = r.Address, 
    City = r.City, 
    PostalCode = r.PostalCode, 
    Province = r.Province, 
    Country = r.Country, 
    Phone = r.Phone, 
    Website = r.Website 
}); 

注:投影法を削除します。メソッドを通じて匿名型を渡す唯一の方法は、ジェネリックスを使用する方法です。例:

C:このプロジェクションを頻繁に行い、プロジェクションクラスを作成したくない場合は、「どうしてですか?」と尋ねます。このプロジェクトコードを頻繁に書くことを避けたい場合は、投影クラスを作成して喜んで、AutoMapperなどのツールを使用することを検討してください。それは今日はかなり一般的です。

+0

ありがとうございます。私はあなたの提案を試み、それは動作しました。私はあなたの答えを受け入れた。しかし、私はあなたが "何かを意味するのか分かりません。メソッドを通して匿名型を渡す唯一の方法はジェネリックス経由です" – programmerboy

+0

@programmerboyコンパイラは強力な型(CLR、DLRは別の日です)で動作します。だから、それぞれの方法は、何が入って来て、何が出ているのかを知る必要があります。メソッドを 'function anonymous MyFunction(anonymous myParam);'として定義することはできません。しかし、メソッドを 'function T MyFunction (T myParam);'として定義することができます。この場合のTは匿名ではなく、一般的なものです。しかし、 'var output = MyFunction(new {a = 'b'});'のように使用すると、Tは匿名型になります。戻り値の型は入力型と同じであり、コンパイラは入力パラメータから型を推論できます。 –

+0

@programmerboy匿名型は動的型ではないことに注意してください。それらは実行時ではなくコンパイル時に作成されます。コンパイラはあなたのために作成しているだけなので、自分でコードを書いたり、ソリューションを乱雑にするたくさんの小さなクラスを持つ必要はありません。 –

0

だから、式の代わりに単純な方法を使用しようとするとどうなりますか?

など。 :

public static object GetProjection(MyObject o){ 
    return new{ 
      Name = o.Name, 
      Address = o.Address, 
      City = o.City, 
      PostalCode = o.PostalCode, 
      Province = o.Province, 
      Country = o.Country, 
      Phone = o.Phone, 
      Website = o.Website 
    }; 
} 

そして、あなたのコントローラで:エンティティへ

var filteredList = db.MyObject.Select(GetProjection).AsQueryable(); 
return Ok(filteredList); 
+0

私はこのエラーのためにコンパイルすることすらできません。 メソッド 'Queryable.Select (IQueryable 、式>)の型引数は、その用途から推論できません。明示的に型引数を指定してみてください/ – programmerboy

+0

このエラーはどこで発生しますか?あなたのコントローラの返品の種類は何ですか?コントローラアクションのソースコードを提供してください –

関連する問題