C#と.NET Framework 4.5.1を使用して、Entity Framework 6.1.3でSQL Serverデータベースからデータを取得しています。
私はこれを持っています:
codes = codesRepo.SearchFor(predicate)
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
そして、実行すると、次のメッセージが表示されます。
LINQ to Entitiesでは、パラメーターなしのコンストラクターと初期化子のみがサポートされています。
私が見つけたすべての例はほとんどこのようなものであるため、タプルを作成する方法がわかりません。
私はこれを試しました:
codes = codesRepo.SearchFor(predicate)
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
そして、このエラーを取得します:
LINQ to Entitiesは、メソッド 'System.Tuple`2 [System.String、System.Byte] Create [String、Byte](System.String、Byte)'メソッドを認識せず、このメソッドをストア式に変換できません。
問題はどこにありますか?
answer by octavioccl は機能しますが、最初にクエリ結果を匿名型に投影してから、列挙可能に切り替えてTupleに変換する方が良いでしょう。これにより、クエリはデータベースから必要なフィールドのみを取得します。
codes = codesRepo.SearchFor(predicate)
.Select(c => new { c.Id, c.Flag })
.AsEnumerable()
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
注:上記のルールはEF6に適用されます。 EF Coreは、タプルコンストラクターを介してタプル(投影またはジョイン/グループキーとして)を自然にサポートします。元のクエリは単純に機能します
codes = codesRepo.SearchFor(predicate)
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
Tuple.Create
メソッドではありません(EF Core 2.x)。
C#7の更新された回答だけで、よりシンプルな構文を使用してValueTuplesを作成できるようになりました。
codes = codesRepo.SearchFor(predicate)
.Select(c => new { c.Id, c.Flag })
.AsEnumerable()
.Select(c => (c.Id, c.Flag))
.ToList();
タプルのプロパティに名前を付けることもできます:
codes = codesRepo.SearchFor(predicate)
.Select(c => new { c.Id, c.Flag })
.AsEnumerable()
.Select(c => (Id: c.Id, Flag: c.Flag))
.ToList();
そのため、Item1またはItem2として使用する代わりに、IdまたはFlagとしてアクセスできます。
これを試して:
codes = codesRepo.SearchFor(predicate)
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
これは、LINQ to entitiesで受け入れられないと通知されました。
別のオプションは、選択する前に結果をメモリにプルすることです。これを行う場合は、.AsEnumerable()の前にすべてのフィルタリングを行うことをお勧めします。これは、テーブル全体をプルバックしてからフィルタリングするのではなく、必要な結果のみをプルバックすることを意味します。
codes = codesRepo.SearchFor(predicate).AsEnumerable()
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
タプル型でコードをもう少し明示的にしたい場合は、Tuple.Create(c.Id、c.Flag)を新しいTuple(c.Id、c.Flag)に変更することもできます。
私は答えを見つけました:
codes = codesRepo.SearchFor(predicate)
.ToList()
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
これを行うにはこのメソッドを使用し、非同期を使用します。
var codes = await codesRepo.SearchFor(predicate)
.Select(s => new
{
Id = s.Id,
Flag = s.Flag
}).FirstOrDefaultAsync();
var return_Value = new Tuple<string, byte>(codes.Id, codes.Flag);
ちょうど私の2セント:これは、タイプ名で私を数回キャッチしました:
ちょっとした例:
private Tuple<string, byte> v1()
{
return new Tuple<string, byte>("", 1);
}
private (string, int) v2()
{
return ("", 1);
}
private (string Id, byte Flag) v3()
{
return ("", 1);
}
よろしく。