私は以下のコードを持っています:
using (DBContext context = new DBContext())
{
myCollection = context.Items.Where(i => i.Type == 1).OrderBy(k => k.Name).Select(w => new
{
Alias = w.Name + string.Format("{0}", w.Id),
Name = w.Name
}).ToArray();
}
実行時に、文字列を連結しようとして、整数w.Idを文字列に変換しようとするとエラーが発生します。
エラーは言う:
エンティティへのLinqはメソッドstring.Formatを認識しません
また、プラス連結記号「+」はサポートされていません。
AsEnumerableを導入することで、これを解決しました。
using (DBContext context = new DBContext())
{
myCollection = context.Items.AsEnumerable().Where(i => i.Type == 1).OrderBy(k => k.Name).Select(w => new
{
Alias = w.Name + string.Format("{0}", w.Id),
Name = w.Name
}).ToArray();
}
しかし、これが最善の解決策なのか、それともこれを行うのにより適した別の方法があるのかを知りたいと思います。アイデア?
コードの最適化の1つは、Where
メソッドの後にAsEnumerable()
を使用することです。そうでない場合は、すべてのエンティティがストレージから返され、LINQ toObjectsを使用してテーブル全体が検査されます。コードをこのように簡単に変更するだけで、where句をSQLで実行し、ストレージから取得するレコードを減らすことができます。一般的なルールは、LINQプロバイダーによって実装されるクエリ句を最初に配置することです。
using (DBContext context = new DBContext())
{
myCollection = context.Items.Where(i => i.Type == 1)
.AsEnumerable().OrderBy(k => k.Name).Select(w => new
{
Alias = w.Name + string.Format("{0}", w.Id),
Name = w.Name
}).ToArray();
}
EFは変換できませんString.Format
SQLに変換しますが、文字列の連結を問題なく処理します。使用する SqlFunctions.StringConvert
の代わりに String.Format
サーバー側で数値を文字列に変換するには:
Select(w => new {
Alias = w.Name + SqlFunctions.StringConvert((double)w.Id),
Name = w.Name
})
それは次のようなものを生成します
SELECT
[Extent1].[Name] + STR( CAST( [Extent1].[Id] AS float)) AS [C1],
[Extent1].[Name] AS [Name]
FROM [dbo].[Items] AS [Extent1]
更新:したがって、この変換をサポートしないEFプロバイダーを使用しています(SQL CEプロバイダーはこのクエリをSQLに変換できません)。残りのオプションは1つだけです。すでに行ったように、計算をクライアント側に移動します。