2009-07-01 19 views
44

可能性の重複:どのようにSQLにLINQを使用してC#の方法から匿名型を返すように


LINQ to SQL: Return anonymous type?は私が(匿名型としてデータを返すSQLクエリ、標準LINQを持っています様々なデータ型の約6列のデータを含む)。

私はこの返されたオブジェクトを、メソッド呼び出し元に返すか、メソッドを含むオブジェクトのプロパティに割り当てることによって、プログラムの他の部分で利用できるようにしたいと考えています。

これは匿名型( "var")なので、どうすればいいですか?

EDIT - ここでのコードは次のとおりです。

using (ormDataContext context = new ormDataContext(connStr)) 
    { 
     var electionInfo = from t1 in context.elections 
        join t2 in context.election_status 
        on t1.statusID equals t2.statusID 
        select new { t1, t2 }; 
    } 
+0

t1、t2フィールドとは何ですか? –

+0

これを元の質問へのブレッドクラムとして残してください。 2つの質問を結合する必要があると思われる場合はコメントを残してください。後で確認します。 –

+0

明確化するために、 'var'は匿名型ではありません。 'var'はコンパイラが型を推論することができるようにするための略語です。この場合、 'electionInfo'は匿名型です。 –

答えて

65

クラスに匿名型を作る...

public class Person 
{ 
    public Person() { 
    } 

    public String Name { get; set; } 
    public DateTime DOB { get; set; } 
} 


Person p = 
    from person in db.People 
    where person.Id = 1 
    select new Person { 
     Name = person.Name, 
     DOB = person.DateOfBirth 
    } 
+0

+1私はちょうどこのような答えを投稿し、それに私を打つ。 :) –

+0

それが起こると嫌い! :) –

+3

匿名のクラスを使用しないことを基本的に言っているので、これははっきりしているようです。なぜなら、LINQサンプルの大部分が、使用するのが非常に難しい場合、LINQサンプルのほとんどがvarを使用しているのだろうと思っています。 – alchemical

19

あなたは匿名の明示的な型であることをC#でいずれかの方法を入力することはできませんタイプ。彼らは話すために「名前を付ける」ことはできないので、メタデータの署名に現れません。

あなたが本当に匿名型の値を返すようにしたい場合は

  1. は、メソッドの戻り値の型はSystem.Objectのも持っている2つのオプションがあります。次に、別の方法で型付き値を取得するために、悪いキャスティング・ハッキングを実行できます。これは非常にですが、私はそれをお勧めしません。
  2. 戻り値の型を正しく取得するには、汎用メソッドと型推論トリックを使用します。これには、あなたのアプローチに非常に興味深いシグネチャ定義が必要です。

匿名タイプは、実際にこのようにして渡されることはありませんでした。そのような方法で関数の間を渡す必要があるときは、型を明示的に定義する方がよいでしょう。

+1

動的データ型を使用する –

+0

'このように関数間で渡す必要がある時点で、型[明らかにあなたは(JavaScript)のゴルファーではありません](https://s-media-cache-ak0.pinimg.com/736x/76/a3/9c/76a39cea29fe872eab52a6b4680f5c66.jpg)。 ; ^) – ruffin

5

Jon Skeetはこれを行う方法についてブログを書いています。これは、かなり正しい名前のHorribly Grotty Hackです。タイトルが示唆するように、あなたは本当に匿名の型を返す方法を探してはいけません。代わりに、この機能を実装する正しい方法であるため、返される型を作成する必要があります。

したがって、返される型の具体的な定義を作成し、それを返すためにクエリに埋め込むことをお勧めします。

+0

...古典的なASPのレコードセットオブジェクトを懐かしく思い出しています...これはコードの複雑さとパフォーマンスのトレードオフのようです小さなプログラムでは大したことではありませんが、数百のdbコールを持つ大規模なプロジェクトでは、取得されたすべてのデータセットに対してカスタムオブジェクトを作成し、dbが変更された場合に変更する必要があります。 。 – alchemical

+0

そして、あなたがしている仕事に適切な技術を使用しているかどうかを検討する必要があります。あなたが必要とするものがハンマーであるときにスペードを使用しないでください。 –

+0

これで、「レコードセット」タイプのオブジェクトを持つことができます。つまり、返されるすべてのタイプが、標準の.NETオブジェクトにラップされたオブジェクトとして格納されます。 – alchemical

6

varを使用しても匿名型にはなりません。 varを使用するということは、この変数を代入の右側で使用できる型にすることを意味します。それはちょうど短い手です。右側のものが実数クラスの場合、その変数はその型になります。例えば

var person = new Person { Name = "bob" }; 

人の変数は、varキーワードを使用していても、タイプの人です。

新しい{名前= ...}を使用して匿名タイプが作成されます。この場合、それは新しい匿名クラスです。あなたが割り当てることができる唯一のものは、使用する既存の名前がないので、var(またはobject)を使って定義された変数です。例えば

:この場合

var person = new { Name = "bob" }; 

、人は実行時に定義された匿名型です。

@Chalkeyによれば、結果を別のメソッドに渡したい場合は、匿名型ではなく名前付きの型を使用します。

匿名タイプを使用する場合は、タイプObjectのオブジェクトとして戻してから、反射を使用してそのプロパティを取得する必要があります。

+0

私は自分のコードでこれを試しましたが、新しく名前を付けた変数(あなたの例では "Person")は、intellisenseでメソッドの使用可能な戻り値の型として確実ではありません... – alchemical

+0

コードを投稿する必要がありますあなたにもう少しアドバイスを与える方法。 – tvanfosson

+0

Thx、私はちょうど質問にコードを追加しました。 – alchemical

0

大きなアプリで結果を渡す必要がある場合は、辞書を使用できます。はい、キャスティング時にオーバーヘッドがありますが、少なくともあなたはオブジェクトを捨てることを減らしています。

2

これは、呼び出し元コードがどのようにデータを使用するかによって異なります。

単純なデータバインディングを行っている場合は、実際にはその型を気にしません(つまり、C#コードのプロパティに明示的にアクセスする必要はありません)。結果をIEnumberableとして渡すことができます。

ほとんどのデータバインディングのケースでは、魔法の文字列を使用して名前でプロパティを呼び出すため、とにかく正確な型は問題になりません。

それ以外の場合は、匿名タイプを名前付きタイプに変換する必要があります。

関連する問題