শর্তসাপেক্ষ লিনক জিজ্ঞাসা


92

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

উত্তর:


156

আপনি যদি নির্দিষ্ট মানদণ্ড পাস হলেই ফিল্টার করতে চান তবে এই জাতীয় কিছু করুন

var logs = from log in context.Logs
           select log;

if (filterBySeverity)
    logs = logs.Where(p => p.Severity == severity);

if (filterByUser)
    logs = logs.Where(p => p.User == user);

এইভাবে করা আপনার এক্সপ্রেশন ট্রিটি আপনি যা চান ঠিক তেমন হতে দেবে। এই ভাবে তৈরি এসকিউএল হ'ল আপনার প্রয়োজনটি ঠিক তেমন হবে এবং এর চেয়ে কম কিছুই নয়।


4
হাই, আপনার কি এন্ডএস এর পরিবর্তে যেখানে ওআরএস ক্লজ তৈরি করার জন্য কোনও পরামর্শ আছে ..?
জন এইচ

4
হ্যাঁ ... এটি করা কিছুটা শক্ত। আমি সবচেয়ে ভাল দেখেছি স্পেসিফিকেশন প্যাটার্নের মাধ্যমে এবং প্রেডিকেটটিকে স্পেসিফিকেশনে টানা এবং তারপরে স্পেসিফিকেশন কল করা হয় O অথবা (সামান্য অন্য স্পেসিফিকেশন)। মূলত আপনাকে নিজের এক্সপ্রেশন ট্রিটি লিখতে হবে কিছুটা। কোড এবং ব্যাখ্যা এখানে উদাহরণস্বরূপ
ড্যারেন কোপ

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

এটি তাদের স্মৃতিতে ফিল্টার করছে না। এটি একটি ক্যোয়ারী তৈরি করছে এবং ডাটাবেসে সমস্ত শর্ত পাঠাচ্ছে (কমপক্ষে বেশিরভাগ লিনক-টু-এক্স সরবরাহকারীদের জন্য)
ড্যারেন কোপ

এই ত্রুটিটি পেয়েছে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.
আলী উমাইয়ার

23

আপনার যদি কোনও তালিকা / অ্যারেতে বেস ফিল্টার করতে হয় তবে নিম্নলিখিতগুলি ব্যবহার করুন:

    public List<Data> GetData(List<string> Numbers, List<string> Letters)
    {
        if (Numbers == null)
            Numbers = new List<string>();

        if (Letters == null)
            Letters = new List<string>();

        var q = from d in database.table
                where (Numbers.Count == 0 || Numbers.Contains(d.Number))
                where (Letters.Count == 0 || Letters.Contains(d.Letter))
                select new Data
                {
                    Number = d.Number,
                    Letter = d.Letter,
                };
        return q.ToList();

    }

4
এটি এখন পর্যন্ত সেরা এবং সবচেয়ে সঠিক উত্তর। শর্তসাপেক্ষ || শুধুমাত্র প্রথম অংশটির তুলনা করে এবং প্রথম অংশটি সত্য হলে দ্বিতীয়টি এড়িয়ে যায় ... সুন্দরভাবে সম্পন্ন হয়েছে!
সেরজ সাগান

4
এই কনস্ট্রাক্টটিতে উত্পন্ন এসকিউএল কোয়েরিতে অভিব্যক্তির 'বা' অংশ অন্তর্ভুক্ত রয়েছে। গৃহীত উত্তর আরও দক্ষ বিবৃতি উত্পন্ন করবে। অবশ্যই ডেটা সরবরাহকারীর অপ্টিমাইজেশনের উপর নির্ভর করে। লিনিক-টু-এসকিউএল-র আরও ভাল অপ্টিমাইজেশন থাকতে পারে, তবে লিনকু-টু-সত্তা নেই।
সানক্যাট 2000

20

আমি ড্যারেনের অনুরূপ উত্তর ব্যবহার করে শেষ করেছি, তবে একটি আইকিউয়েরেবল ইন্টারফেস সহ:

IQueryable<Log> matches = m_Locator.Logs;

// Users filter
if (usersFilter)
    matches = matches.Where(l => l.UserName == comboBoxUsers.Text);

 // Severity filter
 if (severityFilter)
     matches = matches.Where(l => l.Severity == comboBoxSeverity.Text);

 Logs = (from log in matches
         orderby log.EventTime descending
         select log).ToList();

এটি ডেটাবেস হিট করার আগে ক্যোয়ারী তৈরি করে। কমান্ডটি চলবে না। টোললিস্ট () শেষে।


14

শর্তসাপেক্ষ লিনাকের কথা এলে আমি ফিল্টার এবং পাইপ প্যাটার্নটি খুব পছন্দ করি।
http://blog.wekeroad.com/mvc-storefront/mvcstore-part-3/

মূলত আপনি প্রতিটি ফিল্টার কেসের জন্য একটি এক্সটেনশন পদ্ধতি তৈরি করেন যা আইকোয়ারিযোগ্য এবং একটি পরামিতি নেয়।

public static IQueryable<Type> HasID(this IQueryable<Type> query, long? id)
{
    return id.HasValue ? query.Where(o => i.ID.Equals(id.Value)) : query;
}

8

আমি একটি প্রসারিত পদ্ধতির সাহায্যে এটি সমাধান করেছিলাম যাতে একটি সাবলীল অভিব্যক্তির মাঝখানে শর্তসাপেক্ষে LINQ সক্ষম করা যায়। এটি ifবিবৃতি সহ অভিব্যক্তি ভাঙ্গার প্রয়োজনীয়তা সরিয়ে দেয় ।

.If() এক্সটেনশন পদ্ধতি:

public static IQueryable<TSource> If<TSource>(
        this IQueryable<TSource> source,
        bool condition,
        Func<IQueryable<TSource>, IQueryable<TSource>> branch)
    {
        return condition ? branch(source) : source;
    }

এটি আপনাকে এটি করতে দেয়:

return context.Logs
     .If(filterBySeverity, q => q.Where(p => p.Severity == severity))
     .If(filterByUser, q => q.Where(p => p.User == user))
     .ToList();

এখানে এমন একটি IEnumerable<T>সংস্করণ রয়েছে যা বেশিরভাগ অন্যান্য লিনকিউ এক্সপ্রেশন পরিচালনা করবে:

public static IEnumerable<TSource> If<TSource>(
    this IEnumerable<TSource> source,
    bool condition,
    Func<IEnumerable<TSource>, IEnumerable<TSource>> branch)
    {
        return condition ? branch(source) : source;
    }

4

আরেকটি বিকল্প হ'ল এখানে আলোচনা করা প্রিডিকেট বিল্ডারের মতো কিছু ব্যবহার করা । এটি আপনাকে নীচের মত কোড লিখতে দেয়:

var newKids  = Product.ContainsInDescription ("BlackBerry", "iPhone");

var classics = Product.ContainsInDescription ("Nokia", "Ericsson")
                  .And (Product.IsSelling());

var query = from p in Data.Products.Where (newKids.Or (classics))
            select p;

নোট করুন যে আমি লিনক 2 এসকিউএল এর সাথে কাজ করতে পেরেছি। সত্তা ফ্রেমওয়ার্ক এক্সপ্রেশন প্রয়োগ করে না nআনভোক করুন, যা এই পদ্ধতির কাজ করার জন্য প্রয়োজনীয়। আমি এই সমস্যা সম্পর্কে এখানে একটি প্রশ্ন আছে


এটি তাদের সংগ্রহস্থলের শীর্ষে ব্যবসায়ের লজিক স্তর ব্যবহার করে অটোম্যাপার এর মতো একটি সরঞ্জাম যা ডেটা ট্রান্সফার অবজেক্ট এবং সত্তা মডেলগুলির মধ্যে মানচিত্রের জন্য ব্যবহার করে for প্রিকেট নির্মাতা ব্যবহার করে আপনি আপনার আইকিউয়েরেবলকে ফ্ল্যাট করার জন্য অটোম্যাপারে প্রেরণ করার আগে তালিকাকে স্মৃতিতে আনার আগে গতিশীল পরিবর্তন করতে পারবেন। মনে রাখবেন এটি সত্ত্বা ফ্রেমওয়ার্ককেও সমর্থন করে।
ক্রিশ্শের্ম

3

এটা করছি:

bool lastNameSearch = true/false; // depending if they want to search by last name,

whereবিবৃতিতে এই হচ্ছে :

where (lastNameSearch && name.LastNameSearch == "smith")

এর অর্থ হ'ল চূড়ান্ত ক্যোয়ারী তৈরি করা হয়, যদি lastNameSearchহয় falseতবে কোয়েরিটি সর্বশেষ নাম অনুসন্ধানের জন্য কোনও এসকিউএলকে পুরোপুরি বাদ দেবে।


ডেটা সরবরাহকারীর উপর নির্ভর করে। লিনকু-টু-এজেন্সিগুলি এটি ভালভাবে অনুকূল করে না।
সানক্যাট 2000

1

এটি সবচেয়ে সুন্দর জিনিস নয় তবে আপনি ল্যাম্বডা এক্সপ্রেশনটি ব্যবহার করতে পারেন এবং আপনার শর্তগুলি বিকল্পভাবে পাস করতে পারেন। টিএসকিউএলে আমি প্যারামিটারগুলি alচ্ছিক করতে নিম্নলিখিত অনেকগুলি করি:

যেখানে ক্ষেত্র = @ ফিল্ডওয়ার বা @ ফিল্ডভারটি নিখুঁত

আপনি নীচের ল্যাম্বডা (প্রমাণীকরণ যাচাইয়ের উদাহরণ) দিয়ে একই স্টাইলের সদৃশ করতে পারেন:

MyDataContext db = নতুন MyDataContext ();

অকার্যকর রানকুয়েরি (স্ট্রিং প্যারাম 1, স্ট্রিং প্যারাম 2, ইনট? প্যারাম 3)

Func চেকউজার = ব্যবহারকারী =>

((প্যারাম 1. দৈর্ঘ্য> 0)? ইউজার.পারাম 1 == পরম 1: 1 == 1) &&

((প্যারাম 2. দৈর্ঘ্য> 0)? ইউজার.পারাম 2 == পরম 2: 1 == 1) &&

((প্যারাম 3! = নাল)? ইউজার.প্যারাম ৩ == প্যারাম 3: 1 == 1);

ব্যবহারকারী পাওয়া গেছে ইউজার = ডিবি। ব্যবহারকারীরা.সিংল ওআরডিফল্ট (চেক ব্যবহারকারী);

}


1

আমার সম্প্রতি অনুরূপ প্রয়োজনীয়তা ছিল এবং শেষ পর্যন্ত তিনি এমএসডিএন-তে এটি পেয়ে গেলেন। ভিজ্যুয়াল স্টুডিও ২০০ for এর জন্য সিএসআরপ নমুনা

ডাউনলোডের ডায়নামিককুয়ের নমুনায় অন্তর্ভুক্ত ক্লাসগুলি আপনাকে নিম্নলিখিত বিন্যাসে রানটাইম সময়ে গতিশীল ক্যোয়ারী তৈরি করতে দেয়:

var query =
db.Customers.
Where("City = @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("new(CompanyName as Name, Phone)");

এটি ব্যবহার করে আপনি রানটাইম সময়ে গতিশীলভাবে ক্যোয়ারী স্ট্রিং তৈরি করতে পারেন এবং এটি কোথায় () পদ্ধতিতে পাস করতে পারেন:

string dynamicQueryString = "City = \"London\" and Order.Count >= 10"; 
var q = from c in db.Customers.Where(queryString, null)
        orderby c.CompanyName
        select c;

1

আপনি এই এক্সটেনশন পদ্ধতিটি তৈরি এবং ব্যবহার করতে পারেন

public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool isToExecute, Expression<Func<TSource, bool>> predicate)
{
    return isToExecute ? source.Where(predicate) : source;
}

0

কেবল সি # এর && অপারেটরটি ব্যবহার করুন:

var items = dc.Users.Where(l => l.Date == DateTime.Today && l.Severity == "Critical")

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


0

আপনি একটি বাহ্যিক পদ্ধতি ব্যবহার করতে পারেন:

var results =
    from rec in GetSomeRecs()
    where ConditionalCheck(rec)
    select rec;

...

bool ConditionalCheck( typeofRec input ) {
    ...
}

এটি কাজ করবে তবে এক্সপ্রেশন ট্রিগুলিতে ভাঙা যাবে না, যার অর্থ লিনক থেকে এসকিউএল প্রতিটি রেকর্ডের বিপরীতে চেক কোডটি চালাবে।

বিকল্পভাবে:

var results =
    from rec in GetSomeRecs()
    where 
        (!filterBySeverity || rec.Severity == severity) &&
        (!filterByUser|| rec.User == user)
    select rec;

এটি এক্সপ্রেশন ট্রিগুলিতে কাজ করতে পারে যার অর্থ লিনাক থেকে এসকিউএল অনুকূলিত হবে।


0

ঠিক আছে, আমি যা ভেবেছিলাম আপনি ফিল্টার শর্তগুলি পূর্বাভাসের জেনেরিক তালিকায় রাখতে পারেন:

    var list = new List<string> { "me", "you", "meyou", "mow" };

    var predicates = new List<Predicate<string>>();

    predicates.Add(i => i.Contains("me"));
    predicates.Add(i => i.EndsWith("w"));

    var results = new List<string>();

    foreach (var p in predicates)
        results.AddRange(from i in list where p.Invoke(i) select i);               

এর ফলে "আমি", "মাইউ" এবং "কাঁচা" থাকা একটি তালিকার ফলস্বরূপ।

আপনি পূর্বাভাসগুলি সম্পূর্ণ ভিন্ন ফাংশনে ভবিষ্যদ্বাণীগুলির সাথে পূর্বাভাসটি করে যা অপরিবর্তিত সমস্ত ওআরএসকে অনুকূল করে তুলতে পারে।

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