web-dev-qa-db-ja.com

Linq toEntitiesはstring.Formatまたは連結 '+'を認識しません

私は以下のコードを持っています:

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();
}

しかし、これが最善の解決策なのか、それともこれを行うのにより適した別の方法があるのか​​を知りたいと思います。アイデア?

13
Rodri

コードの最適化の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();
}
16

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つだけです。すでに行ったように、計算をクライアント側に移動します。

16