1. ホーム
  2. linq

[解決済み] LINQ to Entities は、メソッド 'System.String Format(System.String, System.Object, System.Object)' を認識しません。

2023-04-08 05:49:51

質問

このようなLinqクエリを持っています。

private void GetReceivedInvoiceTasks(User user, List<Task> tasks)
{
    var areaIds = user.Areas.Select(x => x.AreaId).ToArray();

    var taskList = from i in _db.Invoices
                   join a in _db.Areas on i.AreaId equals a.AreaId
                   where i.Status == InvoiceStatuses.Received && areaIds.Contains(a.AreaId)
                   select new Task {
                       LinkText = string.Format(Invoice {0} has been received from {1}, i.InvoiceNumber, i.Organisation.Name),
                       Link = Views.Edit
                   };
}

しかし、問題があります。タスクを作成しようとしています。新しいタスクごとに、リンクテキストを "Hello" のような定数文字列に設定すると、うまくいきます。しかし、上記では、請求書のプロパティを使用してプロパティリンクテキストを作成しようとしています。

このエラーが発生します。

base {System.SystemException} = {"LINQ to Entities は 'System.String Format(System.String, System.Object, System.Object)' メソッドを認識せず、このメソッドはストア式に変換できません("}。

どなたか理由をご存じですか?また、これを動作させるための代替方法をご存知の方いらっしゃいますか?

どのように解決するのですか?

Entity Frameworkは、SQL側でプロジェクションを実行しようとしています。 string.Format . 使用方法 AsEnumerable() を使って、Linq to Objectsでその部分を強制的に評価することができます。

ベースとなる 前の答えに 私はあなたに与えた私はこのようにあなたのクエリを再構築します。

int statusReceived = (int)InvoiceStatuses.Received;
var areaIds = user.Areas.Select(x=> x.AreaId).ToArray();

var taskList = (from i in _db.Invoices
               where i.Status == statusReceived && areaIds.Contains(i.AreaId)
               select i)
               .AsEnumerable()
               .Select( x => new Task()
               {
                  LinkText = string.Format("Invoice {0} has been received from {1}", x.InvoiceNumber, x.Organisation.Name),
                  Link = Views.Edit
                });

また、クエリの中で関連するエンティティを使用していますね ( Organisation.Name ) を追加していることを確認してください。 Include

var taskList = (from i in _db.Invoices
               where i.Status == statusReceived && areaIds.Contains(i.AreaId)
               select new { i.InvoiceNumber, OrganisationName = i.Organisation.Name})
               .AsEnumerable()
               .Select( x => new Task()
               {
                  LinkText = string.Format("Invoice {0} has been received from {1}", x.InvoiceNumber, x.OrganisationName),
                  Link = Views.Edit
                });