سؤال

لقد كنت أحاول إعادة صياغة تعبير LINQ إلى طريقة ما، وكنت أواجه كلاً من "Internal .NET Framework Data Provider error 1025." و "The parameter 'xyz' was not bound in the specified LINQ to Entities query expression."الاستثناءات.

فيما يلي الأجزاء ذات الصلة من نموذج الكيان (باستخدام EF 4.2 / LINQ للكيانات):

public class Place : Entity
{
    public string OfficialName { get; protected internal set; }
    public virtual ICollection<PlaceName> { get; protected internal set; }
}

public class PlaceName : Entity
{
    public string Text { get; protected internal set; }
    public string AsciiEquivalent { get; protected internal set; }
    public virtual Language TranslationTo { get; protected internal set; }
}

public class Language : Entity
{
    public string TwoLetterIsoCode { get; protected internal set; }
}

النموذج العلائقي الأساسي هو:

Place (1) <-----> (0..*) PlaceName (0..*) <-----> (0..1) Language

أحاول إنشاء استعلام، عند إجراء بحث term, ، في محاولة لايجاد Place الكيانات التي OfficialName يبدأ بـ term أو من لديه PlaceName لمن Text أو AsciiEquivalent يبدأ بالبحث term. (Language ليس المكان الذي أواجه فيه مشكلة، على الرغم من أنه جزء من الاستعلام، لأنه PlaceNameيجب أن يتطابق s فقط مع CultureInfo.CurrentUICulture.TwoLetterIsoLanguageName.)

الكود التالي تعمل:

internal static IQueryable<Place> WithName(this IQueryable<Place> queryable, 
    string term)
{
    var matchesName = OfficialNameMatches(term)
        .Or(NonOfficialNameMatches(term));
    return queryable.AsExpandable().Where(matchesName);
}

private static Expression<Func<Place, bool>> OfficialNameMatches(string term)
{
    return place => place.OfficialName.StartsWith(term);
}

private static Expression<Func<Place, bool>> NonOfficialNameMatches(string term)
{
    var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
    return place => place.Names.Any(
        name =>
        name.TranslationToLanguage != null
        &&
        name.TranslationToLanguage.TwoLetterIsoCode == currentLanguage
        &&
        (
            name.Text.StartsWith(term)
            ||
            (
                name.AsciiEquivalent != null
                &&
                name.AsciiEquivalent.StartsWith(term)
            )
        )
    );
}

ما أحاول القيام به بعد ذلك هو إعادة بناء ملف NonOfficialNameMatches طريقة استخراج name => ... التعبير إلى طريقة منفصلة، ​​بحيث يمكن إعادة استخدامه بواسطة استعلامات أخرى.هنا مثال واحد لقد حاولت، وهو لا يعمل ويطرح الاستثناء "The parameter 'place' was not bound in the specified LINQ to Entities query expression.":

private static Expression<Func<Place, bool>> NonOfficialNameMatches(string term)
{
    return place => place.Names.AsQueryable().AsExpandable()
        .Any(PlaceNameMatches(term));
}

public static Expression<Func<PlaceName, bool>> PlaceNameMatches(string term)
{
    var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
    return name =>
            name.TranslationToLanguage != null
            &&
            name.TranslationToLanguage.TwoLetterIsoCode == currentLanguage
            &&
            (
                name.Text.StartsWith(term)
                ||
                (
                    name.AsciiEquivalent != null
                    &&
                    name.AsciiEquivalent.StartsWith(term)
                )
            );
}

عندما لا يكون لدي .AsExpandable() سلسلة في NonOfficialNameMatches, ، ثم أحصل على "Internal .NET Framework Data Provider error 1025." استثناء.

لقد تابعت نصائح أخرى هنا مثل عدة مجموعات من الاستدعاء .Expand() على المسندات، ولكن دائمًا ينتهي الأمر بأحد الاستثناءات المذكورة أعلاه.

هل من الممكن حتى تحليل هذا التعبير إلى طريقة منفصلة باستخدام LINQ للكيانات باستخدام LinqKit/PredicateBuilder؟ إذا كان الأمر كذلك، كيف؟ما الخطأ الذي افعله؟

هل كانت مفيدة؟

المحلول

يجب أن تعمل الطريقة أدناه:

private static Expression<Func<Place, bool>> NonOfficialNameMatches(string term)
{
    Expression<Func<PlaceName, bool>> placeNameExpr = PlaceNameMatches(term);
    Expression<Func<Place, bool>> placeExpr =
        place => place.Names.Any(name => placeNameExpr.Invoke(name));
    return placeExpr.Expand();
}

يحرر:إضافة شروحات إضافية

ال PlaceNameMatches الطريقة تعمل كما كتبتها.كانت مشكلاتك تتعلق بكيفية استخدامك لهذه الطريقة.إذا كنت تريد استبعاد أجزاء من التعبير، فاتبع الخطوات الثلاث التي قمت بها في الطريقة أعلاه.

  1. قم بتعيين متغير محلي للتعبير الذي تم إنشاؤه بواسطة إحدى الطرق.

  2. قم بتعيين متغير محلي آخر إلى تعبير جديد يستدعي تعبير المتغير المحلي.

  3. اتصل بـ LinkKit Expand طريقة:سيؤدي هذا إلى توسيع أي تعبيرات تم استدعاؤها

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top