সত্তা থেকে লিনকিউ পদ্ধতিটি স্বীকৃতি দেয় না


116

লিনক ক্যোয়ারী করার চেষ্টা করার সময় আমি নিম্নলিখিত ত্রুটিটি পেয়েছি:

সংস্থাগুলি থেকে লিনকিউ 'বুলিয়ান ইসচারিটিম্যাচিং (সিস্টেম.স্ট্রিং, সিস্টেম.স্ট্রিং)' পদ্ধতিটি স্বীকৃতি দেয় না এবং এই পদ্ধতির কোনও স্টোর এক্সপ্রেশন হিসাবে অনুবাদ করা যায় না।

আমি পূর্ববর্তী অনেকগুলি প্রশ্ন পড়েছি যেখানে লোকেরা একই ত্রুটি পেয়ে থাকে এবং আমি যদি এটি সঠিকভাবে বুঝতে পারি তবে এটি লিনকিউ থেকে সংস্থাগুলির জন্য সম্পূর্ণ লিনক ক্যোয়ারী এক্সপ্রেশনটি একটি সার্ভার ক্যোয়ারীতে অনুবাদ করা প্রয়োজন, এবং তাই আপনি কোনও বাইরের পদ্ধতিতে কল করতে পারবেন না এটা. আমি আমার দৃশ্যের এমন কিছুতে রূপান্তর করতে সক্ষম হইনি যা এখনও কাজ করে, এবং আমার মস্তিষ্ক গলে যেতে শুরু করেছে, তাই আমি আশা করছিলাম যে কেউ আমাকে সঠিক দিকে নির্দেশ করতে পারে। আমরা সত্তা ফ্রেমওয়ার্ক এবং স্পেসিফিকেশন প্যাটার্ন ব্যবহার করছি (এবং আমি উভয়ের পক্ষে নতুন)।

এখানে কোডটি যা স্পেসিফিকেশন ব্যবহার করে:

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

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

এখানে লিনাক এক্সপ্রেশন:

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

এখানে ইসচারিটি ম্যাচিং পদ্ধতিটি রয়েছে:

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

আপনি কোনো অধিক তথ্য প্রয়োজন হলে আমাকে জানতে দিন।

অনেক ধন্যবাদ,

Annelie



পাশাপাশি এটি পরীক্ষা করে দেখুন, ধন্যবাদ!
অ্যানেলি

1
আপনি Find()যখন IsSatisfied()এটির অভ্যন্তরীণ ব্যবহার করবেন তখন আপনি কীভাবে ব্যবহার করছেন তা দেখতে সুন্দর লাগবে।
এলিসন

উত্তর:


124

আপনি যেমনটি আবিষ্কার করেছেন, সত্ত্বার ফ্রেমওয়ার্ক আসলে আপনার সি # কোডটিকে তার ক্যোয়ারির অংশ হিসাবে চালাতে পারে না। এটি ক্যোয়ারিকে সত্যিকারের এসকিউএল স্টেটমেন্টে রূপান্তর করতে সক্ষম হতে হবে। এটি কাজ করার জন্য, আপনাকে আপনার ক্যোয়ারী এক্সপ্রেশনটিকে এমন একটি অভিব্যক্তিতে পুনর্গঠন করতে হবে যা সত্তা ফ্রেমওয়ার্ক পরিচালনা করতে পারে।

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

1
সন্দেহ হলে এটি সন্ধান করুন: stackoverflow.com/questions/2352764/…
ক্রিস হেইস

2
একটি বিল্ডিং ফিরে Expression<Func<T,type>>এটি একটি খুব সুন্দর পদ্ধতির হয়।
ট্র্যাভিস জে

আপনি কীভাবে এটি একটি লিনকিউ এক্সপ্রেশনে ব্যবহার করবেন? আমি পুনরায় ব্যবহারের যোগ্য যেখানে ধারাটি হিসাবে এটির মতো কিছু করতে চাই তবে এটি কার্যকর করার সাথে লড়াই করছি।
জোড়গারথ

4
সম্পাদনা: কিছুই নয়, এটি হবে:context.Where(IsSatisfied())
জোড়গারথ

মূল অংশ: "সত্তা ফ্রেমওয়ার্কটি আপনার সি #
কোডটিকে

1

আমি এই কোডে একই ত্রুটি পেয়েছি:

 var articulos_en_almacen = xx.IV00102.Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

এটি ঠিক ত্রুটি ছিল:

System.NotSupporterException: 'LINQ to Instants' পদ্ধতিটি চিনতে পারে না 'বুলিয়ান অস্তিত্বগুলি (System.Predicate`1 [conect_gp.Models.almacenes_por_sucursal]) পদ্ধতি এবং এই পদ্ধতিটি কোনও স্টোর এক্সপ্রেশনটিতে অনুবাদ করা যায় না' '

আমি এইভাবে সমাধান করেছি:

var articulos_en_almacen = xx.IV00102.ToList().Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

আমি আমার টেবিলের আগে একটি .ToList () যুক্ত করেছি, এটি সত্তা এবং লিনক কোডটি ডিকুয়াল করে এবং আমার পরবর্তী লিংক প্রকাশটি এড়াতে এড়াতে

দ্রষ্টব্য: এই সমাধানটি সর্বোত্তম নয়, কারণ সত্তা ফিল্টারিং এড়ানো এবং কেবল সমস্ত টেবিলটি মেমরিতে লোড করে


1
বেশিরভাগ সময় এটি সবচেয়ে সহজ সমাধান তবে সমস্ত অবজেক্টটি লোড না করার জন্য আমি সাধারণত আমার যা প্রয়োজন তা দিয়ে .ToList () এর আগে একটি বেনাম নির্বাচন করুন ... xx.Select (x => new {x.Id, x.DateTimeUpdate L)। টুলিস্ট ()। (X => নতুন {x.Id, ডেটটাইমআপডেট = এক্স.ডেটটাইমআপডেট। টোস্ট্রিং ("ডিডি / এমএম / ইয়াই")})
ডায়াগনেস

0

যদি কেউ VB.Net উত্তর খুঁজছেন (যেমন আমি প্রথম দিকে ছিলাম), এখানে তা:

Public Function IsSatisfied() As Expression(Of Func(Of Charity, String, String, Boolean))

Return Function(charity, name, referenceNumber) (String.IsNullOrWhiteSpace(name) Or
                                                         charity.registeredName.ToLower().Contains(name.ToLower()) Or
                                                         charity.alias.ToLower().Contains(name.ToLower()) Or
                                                         charity.charityId.ToLower().Contains(name.ToLower())) And
                                                    (String.IsNullOrEmpty(referenceNumber) Or
                                                     charity.charityReference.ToLower().Contains(referenceNumber.ToLower()))
End Function

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.