1. ホーム
  2. .net

[解決済み] LINQ to Entitiesはメソッドを認識しません。

2022-02-17 08:27:22

質問

linqクエリを実行しようとすると、以下のエラーが発生します。

LINQ to Entitiesはメソッド'Boolean'を認識しません。 IsCharityMatching(System.String, System.String)'メソッドがあり、このメソッドは メソッドはストア式に変換できません。

私が正しく理解すれば、LINQ to Entitiesはlinqクエリ式全体をサーバクエリに変換する必要があり、そのためその中で外部メソッドを呼び出すことができないからです。私はまだ自分のシナリオを動作するものに変換することができず、私の脳は溶け始めているので、誰かが正しい方向を示してくれることを期待していました。私たちはEntity Frameworkと仕様パターンを使用しています(そして私は両方とも初めてです)。

以下は、その仕様を利用したコードです。

ISpecification<Charity> specification = new CharitySearchSpecification(charityTitle, charityReference);

charities = charitiesRepository.Find(specification).OrderBy(p => p.RegisteredName).ToList();

これがlinq式です。

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    return p => p.IsCharityMatching(this.charityName, this.charityReference);
}

以下は、IsCharityMatchingメソッドです。

public bool IsCharityMatching(string name, string referenceNumber)
{
    bool exists = true;

    if (!String.IsNullOrEmpty(name))
    {
        if (!this.registeredName.ToLower().Contains(name.ToLower()) &&
            !this.alias.ToLower().Contains(name.ToLower()) &&
           !this.charityId.ToLower().Contains(name.ToLower()))
        {
            exists = false;
        }
    }

    if (!String.IsNullOrEmpty(referenceNumber))
    {
        if (!this.charityReference.ToLower().Contains(referenceNumber.ToLower()))
        {
            exists = false;
        }
    }

    return exists;
}

また何かあれば教えてください。

ありがとうございました。

アネリー

解決方法は?

お分かりのように、Entity Framework はクエリの一部として C# コードを実際に実行することができません。クエリを実際のSQL文に変換する必要があります。そのためには、クエリ式をEntity Frameworkが処理できる式に再構築する必要があります。

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    string name = this.charityName;
    string referenceNumber = this.referenceNumber;
    return p => 
        (string.IsNullOrEmpty(name) || 
            p.registeredName.ToLower().Contains(name.ToLower()) ||
            p.alias.ToLower().Contains(name.ToLower()) ||
            p.charityId.ToLower().Contains(name.ToLower())) &&
        (string.IsNullOrEmpty(referenceNumber) ||
            p.charityReference.ToLower().Contains(referenceNumber.ToLower()));
}