লিনক: শর্ত সাপেক্ষে যেখানে শর্ত যুক্ত


102

আমার এই মত একটি প্রশ্ন আছে

(from u in DataContext.Users
       where u.Division == strUserDiv 
       && u.Age > 18
       && u.Height > strHeightinFeet  
       select new DTO_UserMaster
       {
         Prop1 = u.Name,
       }).ToList();

বয়স, উচ্চতা যেমন এই কোয়েরিটি চালানোর পদ্ধতিতে এই শর্তাদি সরবরাহ করা হয়েছিল কিনা তার উপর ভিত্তি করে আমি বিভিন্ন শর্ত যুক্ত করতে চাই। সমস্ত শর্তাবলী ব্যবহারকারী বিভাগ অন্তর্ভুক্ত করা হবে। যদি বয়স সরবরাহ করা হয় তবে আমি এটি ক্যোয়ারিতে যুক্ত করতে চাই। একইভাবে, উচ্চতা সরবরাহ করা হলে আমি এটিও যুক্ত করতে চাই।

এটি যদি এসকিএল ক্যোয়ারী ব্যবহার করে করা হত তবে আমি স্ট্রিং বিল্ডারকে তাদের মূল এসআরএসকিউএল কোয়েরিতে সংযুক্ত করার জন্য ব্যবহার করতাম। তবে এখানে লিন্কে আমি কেবলমাত্র একটি আইএফ শর্ত ব্যবহার করার কথা ভাবতে পারি যেখানে আমি একই প্রশ্নটি তিনবার লিখব, প্রতিটি আইএফ ব্লকের একটি অতিরিক্ত শর্ত রয়েছে having এই কাজ করতে একটি ভাল উপায় আছে কি?

উত্তর:


182

আপনি যদি কল না করেন ToList()এবং ডিটিও টাইপটিতে আপনার চূড়ান্ত ম্যাপিং, Whereআপনি যাওয়ার সাথে সাথে ক্লজগুলি যুক্ত করতে পারেন এবং ফলাফলটি তৈরি করতে পারেন:

var query = from u in DataContext.Users
   where u.Division == strUserDiv 
   && u.Age > 18
   && u.Height > strHeightinFeet
   select u;

if (useAge)
   query = query.Where(u => u.Age > age);

if (useHeight)
   query = query.Where(u => u.Height > strHeightinFeet);

// Build the results at the end
var results = query.Select(u => new DTO_UserMaster
   {
     Prop1 = u.Name,
   }).ToList();

এটি এখনও ডাটাবেসে কেবলমাত্র একক কলের ফলাফল করবে, যা কার্যকরভাবে এক পাসে কোয়েরি লেখার মতো দক্ষ।


1
"Var কোয়েরি = .." বিবৃতিতে আমাকে যেখানে সমস্ত শর্ত রেখে দেওয়ার দরকার আছে?
ব্যবহারকারী 20358

4
পরবর্তীকালে শর্তগুলি ওআর বা হিসাবে হিসাবে সংহত হয়?
vi100

4
@ vi100 এগুলি অতিরিক্ত ফিল্টার হবে, সুতরাং এবং
রিড

সরলতার জন্য ধার্মিকতা ধন্যবাদ! আমি উপরের দিক থেকে আরও বেশি পাঠযোগ্য, যখন 20+ লাইন লিনাকের কোয়েরিগুলি দেখে এত অসুস্থ হয়ে পড়েছি
Justanotherdev

আমি কেন এই ত্রুটিটি পাচ্ছিLINQ to Entities does not recognize the method 'System.String get_Item(System.String)' method, and this method cannot be translated into a store expression.
আলী উমার

18

আমি সাধারণত পদ্ধতিতে শৃঙ্খলা ব্যবহার করি তবে একই সমস্যা থাকে। এবং এখানে আমি ব্যবহার এক্সটেনশন

public static IQueryable<T> ConditionalWhere<T>(
        this IQueryable<T> source, 
        Func<bool> condition,
        Expression<Func<T, bool>> predicate)
    {
        if (condition())
        {
            return source.Where(predicate);
        }

        return source;
    }

এটি চেইন ব্রেক এড়াতে সহায়তা করে। এছাড়াও একই ConditionalOrderByএবং ConditionalOrderByDescendingসহায়ক।


সহায়ক, তবে আপনি দয়া করে এটি ব্যবহারে কেমন দেখতে হবে তার একটি উদাহরণ যুক্ত করুন।
সানক্যাট 2000

1
এটির মতো হওয়া উচিত: var ফলস = অপেক্ষায় ডিবি.ফল। শর্তযুক্ত শর্ত (())> রঙ! = নাল, চ => চ .রাইপ == পাকা) .ToListAsync ();
ইউরি গ্রানোভস্কি

4
দুর্দান্ত কাজ! ধন্যবাদ! আমি আরও বেশি স্বজ্ঞাত করে তুলতে যেখানে কোনও প্রতিনিধি অপ্রয়োজনীয় জটিলতা যুক্ত করে, আমি কোনও ফাংশনের পরিবর্তে সাধারণ বুলিয়ান মান হিসাবে শর্তের জন্য একটি ওভারলোডও করেছি । আমি এখনই প্রায়শই এই এক্সটেনশন পদ্ধতিটি ব্যবহার করি এবং আপনার সমাধানটির খুব প্রশংসা করি।
সানকাট 2000

17

একটি বিকল্প

bool? age = null

(from u in DataContext.Users
           where u.Division == strUserDiv 
           && (age == null || (age != null && u.Age > age.Value))
           && u.Height > strHeightinFeet  
           select new DTO_UserMaster
           {
             Prop1 = u.Name,
           }).ToList();

অথবা আপনি লিনাকের জন্য পদ্ধতি সিনট্যাক্সে স্যুইচ করতে পারেন এবং শর্তটি যেখানে অনুচ্ছেদে সংযুক্তি যুক্ত করতে ব্যবহার করতে পারেন।


3

কেবল আমি এটি আমার ক্লোজ হিসাবে এটি ব্যবহার করছি

    public IList<ent_para> getList(ent_para para){
     db.table1.Where(w=>(para.abc!=""?w.para==para.abc:true==true) && (para.xyz!=""?w.xyz==para.xyz:true==true)).ToList();
}

3

নির্দিষ্ট ঘনত্বের উপর ভিত্তি করে যেখানে শর্ত যুক্ত করুন ...

from u in DataContext.Users
where u.Division == strUserDiv 
&& u.Age != null ? u.Age > 18 : 1== 1
&& u.Height != null ? u.Height > 18 : 1== 1
&& u.Height != null ? u.Height > 18 : 1== 1
 select new DTO_UserMaster
       {
         Prop1 = u.Name,
       }).ToList();

2

অনুরূপ কাজ করতে আমার কোড এখানে। এটি আমার ডাব্লুসিএফ সোপ ওয়েব পরিষেবা এপিআইয়ের একটি পদ্ধতি।

    public FruitListResponse GetFruits(string color, bool? ripe)
    {
        try
        {
            FruitContext db = new FruitContext();
            var query = db.Fruits.Select(f => f);
            if (color != null)
            {
                query = query.Where(f => f.Color == color);
            }
            if (ripe != null)
            {
                query = query.Where(f => f.Ripe == ripe);
            }
            return new FruitListResponse
            {
                Result = query.Select(f => new Fruit { Id = f.FruitId, Name = f.Name }).ToList()
            };
        }
        catch (Exception e)
        {
            return new FruitListResponse { ErrorMessage = e.Message };
        }
    }

বেস ক্যোয়ারির Select(f => f)অর্থ হ'ল মূলত সমস্ত কিছুই এবং Whereক্লজগুলি ally চ্ছিকভাবে এর সাথে সংযুক্ত থাকে। ফাইনালটি Selectচ্ছিক। আমি ফলশ্রুতিতে "ফল" বস্তুতে ডাটাবেস সারি অবজেক্টগুলিকে রূপান্তর করতে ব্যবহার করি।


0

নিম্নলিখিত প্যারামিটার ধরে নেওয়া,

Int? Age = 18;

কেবল ব্যবহার &&এবং ||শর্তসাপেক্ষ অপারেটরগুলির সাথে আমাদের আরও একটি সংস্করণ থাকতে পারে।

(from u in DataContext.Users
where u.Division == strUserDiv 
    && (Age == null || u.Age > Age)
    && (Param1 == null || u.param1 == Param1)
    && u.Height > strHeightinFeet
select new DTO_UserMaster
{
    Prop1 = u.Name,
}).ToList();

প্যারাম 1 এর মতো আপনি অনুসন্ধানের শর্তের জন্য যে কোনও সংখ্যক পরামিতি যুক্ত করতে পারেন।


0

আমি সবেমাত্র এটিকে অন্য কিছু সন্ধান করতে পেরেছি, তবে ভেবেছিলাম আমি ল্যাম্বডা সংস্করণটি ফেলে দেব।

প্রথমত, আমি একটি ডেটা স্তরে পরামিতিগুলি পাস করার জন্য এই জাতীয় শ্রেণি তৈরি করব:

   public class SearchParameters() {
       public int? Age {get; set;}
       public string Division {get;set;}
       etc
    }

তারপরে, আমার ডেটা স্তরে, এরকম কিছু:

public IQueryable<User> SearchUsers(SearchParameters params) 
{
    var query = Context.Users;
    if (params.Age.HasValue)
    {
         query = query.Where(u => u.Age == params.Age.Value);
    }
    if (!string.IsNullOrEmpty(params.Division)
    {
        query = query.Where(u => u.Division == params.Division);
    }
    etc
    return query;
}

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


ওহো, আমি জন হেন্কেলের উত্তর দেখতে পেলাম না। একই ধারণা।
স্কট পিটারসন

0

কেবলমাত্র এখানে উপরোক্ত গৃহীত উত্তরের সাথে যুক্ত করতে , আপনি যদি একটি যোগদানের উপর গতিশীল অনুসন্ধান করছেন, তবে প্রাথমিক লিঙ্ক ক্যোয়ারিতে উভয় টেবিল (টি 1, টি 2) দিয়ে একটি নতুন অবজেক্ট ফিরে আসার কথা বিবেচনা করুন যাতে আপনি শর্তসাপেক্ষে পৃথকভাবে অ্যাক্সেস করতে পারেন অনুসন্ধান করুন।

var query = from t1 in _context.Table1
            join t2 in _context.Table2 on t1.Table1Id equals t2.Table1IdId
            select new { t1, t2 };

        if (!string.IsNullOrEmpty(searchProperty1))
        {
            query = query.Where(collection => collection.t1.TableColumn == searchProperty1);
        }
        if (!string.IsNullOrEmpty(searchProperty2))
        {
            query = query.Where(collection => collection.t2.TableColumn == searchProperty2);
        }
        ....etc.

আমি দুটি সারণীতে যোগদান এবং টেবিলগুলির যে কোনও একটিতে নির্দিষ্ট কলাম অনুসন্ধান করার ক্ষেত্রে আমি উত্তরটি এখানে পেয়েছি

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