স্ট্রিং.আইএসএনলআরওরাইটস্পেস লিনকুই এক্সপ্রেশন-এ


151

আমার কাছে নিম্নলিখিত কোড রয়েছে:

return this.ObjectContext.BranchCostDetails.Where(
    b => b.TarrifId == tariffId && b.Diameter == diameter
        || (b.TarrifId==tariffId && !string.IsNullOrWhiteSpace(b.Diameter))
        || (!b.TarrifId.HasValue) && b.Diameter==diameter);

এবং কোডটি চালানোর চেষ্টা করার সময় আমি এই ত্রুটিটি পেয়েছি:

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

আমি কীভাবে এই সমস্যাটি সমাধান করতে পারি এবং এর চেয়ে কোডটি আরও ভাল লিখতে পারি?

উত্তর:


263

আপনাকে প্রতিস্থাপন করতে হবে

!string.IsNullOrWhiteSpace(b.Diameter)

সঙ্গে

!(b.Diameter == null || b.Diameter.Trim() == string.Empty)

লিনক থেকে সত্তার জন্য এটি অনুবাদ করা যায়:

DECLARE @p0 VarChar(1000) = ''
...
WHERE NOT (([t0].[Diameter] IS NULL) OR (LTRIM(RTRIM([t0].[Diameter])) = @p0))

এবং লিনকের পক্ষে এসকিউএল প্রায় কিন্তু একরকম নয়

DECLARE @p0 NVarChar(1000) = ''
...
WHERE NOT (LTRIM(RTRIM([t0].[TypeName])) = @p0)

3
কেন? এই কোডটি সংকলন করে:List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;
এরিক জে।

37
এটি সংকলন করতে পারে তবে লিনক সত্ত্বায় এটি এসকিউএল অনুবাদ করবে না। পদ্ধতি 'বুলিয়ান ইসনুলআরওহাইটস্পেস (সিস্টেম.স্ট্রিং)' এর এসকিউএলে কোনও সমর্থনযোগ্য অনুবাদ নেই। একইটি ইসনুলআরএম্পটির জন্য প্রযোজ্য।
ফিল

1
লিঙ্ক থেকে এসকিউএল
ফিল

3
সাবধানতার একটি শব্দ: এটি 'স্ট্রিং.এম্পটি' ওভার "" (খালি স্ট্রিং ওরফে) নিয়োগের ক্ষেত্রে অত্যন্ত গুরুত্বের বিষয়। পূর্বেরটি কাজ করে যা পরবর্তীকালে হয় না (কমপক্ষে যতদূর ওরাকলির ইএফ ড্রাইভার সম্পর্কিত)। আকা আপনি যদি ব্যবহার করেন: বি.ডি.ই. ব্যাস। ট্রিম () == "" <- এটি উদ্দেশ্য হিসাবে কাজ করবে না (আমি জানি পাগল ...)
এক্সডিএস

মনে হয় ট্রাম () কমপক্ষে মোঙ্গোডিবি ব্যবহার করে অনুসন্ধানের জন্যও সমর্থিত নয় riড্রাইভার
লিয়ান্ড্রো এখানে

20

এই ক্ষেত্রে IQueryable<T>এবং এর মধ্যে পার্থক্য করা গুরুত্বপূর্ণ IEnumerable<T>। সংক্ষেপেIQueryable<T> একটি লিনকিউ সরবরাহকারী একটি অপ্টিমাইজড ক্যোয়ারী সরবরাহ করার জন্য প্রক্রিয়া করে। এই রূপান্তরকালে সমস্ত সি # স্টেটমেন্ট সমর্থিত হয় না, কারণ এটি হয় কোনও ব্যাক-এন্ড নির্দিষ্ট সন্ধানের (যেমন এসকিউএল) তে অনুবাদ করা সম্ভব নয় বা প্রয়োগকারীরা বিবৃতিটির প্রয়োজনীয়তার পূর্বেই প্রত্যাশা করেনি।

বিপরীতে IEnumerable<T>কংক্রিট অবজেক্টগুলির বিরুদ্ধে কার্যকর করা হয় এবং সুতরাং, রূপান্তরিত হবে না। সুতরাং, এটি বেশ সাধারণ যে কনস্ট্রাক্টসগুলি, যাগুলির সাথে ব্যবহারযোগ্য IEnumerable<T>তা ব্যবহার করা যায় না IQueryable<T>এবং IQueryables<T>বিভিন্ন লিনকিউ সরবরাহকারীদের দ্বারা সমর্থিত একই ফাংশনগুলির সেটকে সমর্থন করে না।

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

সুতরাং উপরের কোডটিও এ জাতীয়ভাবে পুনরায় লেখা যেতে পারে:

return this.ObjectContext.BranchCostDetails
    .AsEnumerable()
    .Where(
        b => b.TarrifId == tariffId && b.Diameter == diameter
        || (b.TarrifId==tariffId && !string.IsNullOrWhiteSpace(b.Diameter))
        ||(!b.TarrifId.HasValue) && b.Diameter==diameter
    );

দ্রষ্টব্য: ফিলের উত্তরের চেয়ে এই কোডটির উচ্চতর পারফরম্যান্স প্রভাব পড়বে । তবে এটি নীতিটি দেখায়।


10

স্ট্রিংয়ের রেফারেন্সগুলি সনাক্ত করতে একটি এক্সপ্রেশন ভিজিটর ব্যবহার করুন sআইসনুলআরওহাইটস্পেস এবং এগুলিকে একটি সহজ অভিব্যক্তি হিসাবে বিভক্ত করুন (x == null || x.Trim() == string.Empty)

সুতরাং নীচে এটি ব্যবহার করার জন্য একটি বর্ধিত দর্শনার্থী এবং একটি এক্সটেনশন পদ্ধতি রয়েছে। এটি ব্যবহারের জন্য কোনও বিশেষ কনফিগারেশন প্রয়োজন নেই, কেবল যেখানে থাকুন পরিবর্তে কোথাওএক্সএক্স কল করুন।

public class QueryVisitor: ExpressionVisitor
{
    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
        if (node.Method.IsStatic && node.Method.Name == "IsNullOrWhiteSpace" && node.Method.DeclaringType.IsAssignableFrom(typeof(string)))
        {
            //!(b.Diameter == null || b.Diameter.Trim() == string.Empty)
            var arg = node.Arguments[0];
            var argTrim = Expression.Call(arg, typeof (string).GetMethod("Trim", Type.EmptyTypes));

            var exp = Expression.MakeBinary(ExpressionType.Or,
                    Expression.MakeBinary(ExpressionType.Equal, arg, Expression.Constant(null, arg.Type)),
                    Expression.MakeBinary(ExpressionType.Equal, argTrim, Expression.Constant(string.Empty, arg.Type))
                );

            return exp;
        }

        return base.VisitMethodCall(node);
    }
}

public static class EfQueryableExtensions
{
    public static IQueryable<T> WhereEx<T>(this IQueryable<T> queryable, Expression<Func<T, bool>> where)
    {
        var visitor = new QueryVisitor();
        return queryable.Where(visitor.VisitAndConvert(where, "WhereEx"));
    }
}

সুতরাং আপনি যদি চালনা করেন তবে myqueryable.WhereEx(c=> !c.Name.IsNullOrWhiteSpace())এটি !(c.Name == null || x.Trim() == "")যে কোনও (লিনক থেকে এসকিএল / সত্তা) পাস করার আগে রূপান্তরিত হবে এবং এসকিউএল তে রূপান্তরিত হবে।


এ জাতীয় সাধারণ প্রয়োজনের জন্য ফিলের জবাবের চেয়ে অনেক জটিল, তবে এক্সপ্রেশনভিসিটার সম্পর্কিত শিক্ষামূলক উদ্দেশ্যে অত্যন্ত আকর্ষণীয়, ধন্যবাদ
আফ্রিক্ট করুন

2

হোয়াইটস্পেস যাচাই করতে আপনি এটি ব্যবহার করতে পারেন:

b.Diameter!=null && !String.IsNullOrEmpty(b.Diameter.Trim())

6
ব্যাসটি শূন্য হলে এটি একটি ব্যতিক্রম ছুঁড়ে ফেলবে।
ওকান কোসিজিগ

@ ওকানকোসিগিত আপনি ঠিক বলেছেন। আমি উত্তর সম্পাদনা করেছি। :)
মাজিদ

0
!String.IsNullOrEmpty(b.Diameter.Trim()) 

যদি ব্যতিক্রম b.Diameterহয় নিক্ষেপ করা হবে null
আপনি যদি এখনও আপনার বিবৃতি ব্যবহার করতে চান তবে আরও ভালভাবে এই চেকটি ব্যবহার করুন

!String.IsNullOrWhiteSpace(b.Diameter), IsNullOrWhiteSpace = IsNullOrEmpty + WhiteSpace

2
স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম! সবার আগে, উত্তরদাতা হিসাবে এসওতে অংশ নেওয়ার জন্য আপনাকে ধন্যবাদ। একটি পরিষ্কার এবং সহজ পড়া সহজ উত্তর তৈরি করতে দয়া করে বিন্যাসে একবার দেখুন ।
হিল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.