সত্তা থেকে লিঙ্ক - এসকিউএল "ইন" ধারা


230

টি-এসকিউএল এ আপনার কাছে একটি কোয়েরি থাকতে পারে:

SELECT * FROM Users WHERE User_Rights IN ("Admin", "User", "Limited")

কীভাবে আপনি এটি লাইনকিউতে সত্তা কোয়েরিতে প্রতিলিপি করবেন? এটা কি সম্ভব?

উত্তর:


349

আপনি এটি সম্পর্কে যেভাবে ভাবছেন তার নিরিখে এটি আপনার মাথা ঘুরিয়ে দেওয়া দরকার। প্রযোজ্য ব্যবহারকারীর অধিকারের পূর্বনির্ধারিত সংকলনে বর্তমান আইটেমটির ব্যবহারকারীর অধিকারগুলি অনুসন্ধান করতে "ইন" না করার পরিবর্তে আপনি ব্যবহারকারীর অধিকারের একটি পূর্বনির্ধারিত সেট জিজ্ঞাসা করছেন যদি এতে বর্তমান আইটেমটির প্রযোজ্য মান থাকে। আপনি নেট থেকে নিয়মিত তালিকায় কোনও আইটেমটি দেখতে পাবেন ঠিক ঠিক একই পথে।

লিনকিউ ব্যবহার করে এটি করার দুটি উপায় রয়েছে, একটি কোয়েরি সিনট্যাক্স এবং অন্যটি পদ্ধতি সিনট্যাক্স ব্যবহার করে। মূলত, এগুলি হ'ল এবং আপনার পছন্দের উপর নির্ভর করে বিনিময়যোগ্যভাবে ব্যবহার করা যেতে পারে:

অনুসন্ধান সিনট্যাক্স:

var selected = from u in users
               where new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights)
               select u

foreach(user u in selected)
{
    //Do your stuff on each selected user;
}

পদ্ধতি সিনট্যাক্স:

var selected = users.Where(u => new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights));

foreach(user u in selected)
{
    //Do stuff on each selected user;
}

এই উদাহরণে আমার ব্যক্তিগত পছন্দটি পদ্ধতি সিনট্যাক্স হতে পারে কারণ ভেরিয়েবলটি বরাদ্দের পরিবর্তে আমি বেনামে এইরকম কল করে ভবিষ্যদ্বাণীটি করতে পারি:

foreach(User u in users.Where(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
    //Do stuff on each selected user;
}

কৃত্রিমভাবে এটি আরও জটিল দেখায় এবং ল্যাম্বডা এক্সপ্রেশন বা প্রতিনিধিদের ধারণাটি বুঝতে হবে যা ঘটছে তা সত্যিই খুঁজে বের করার জন্য, তবে আপনি দেখতে পাচ্ছেন যে এই কোডটি ন্যায্য পরিমাণে ঘনীভূত করে।

এটি সব আপনার কোডিং শৈলীতে এবং পছন্দটিতে নেমে আসে - আমার তিনটি উদাহরণ একই জিনিসটি কিছুটা ভিন্নভাবে করে।

বিকল্প উপায় এমনকি লিনকিউ ব্যবহার করে না, আপনি "ফাইন্ডএল" এর সাথে "যেখানে" প্রতিস্থাপন করে একই পদ্ধতি সিনট্যাক্স ব্যবহার করতে পারেন এবং একই ফলাফল পাবেন, যা নেট .০.০ এও কাজ করবে:

foreach(User u in users.FindAll(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
    //Do stuff on each selected user;
}

আমি উত্তর হিসাবে চিহ্নিত করতে খুব দ্রুত ছিলাম, তবে আমি একটিও পাই না {"অ্যাডমিন", "ব্যবহারকারী", "সীমাবদ্ধ"} ভিএস ২০০8 পরে কোডটি কিছুটা পছন্দ করে না।
স্টিভেনএমসিডি

1
আমার নাম "ফেইলবয়" এর সাথে সত্য, আমি এটি বের করেছিলাম: পিআই একটি স্ট্রিং [] লাগিয়েছে এবং তারপরে এটি ব্যবহার করে এবং এটি কাজ করে। ধন্যবাদ!
স্টিভেনএমসিডি

দুঃখিত, আমি বেনামে অ্যারে নতুন করতে ভুলে গেছি;) আমি আমার কোড উদাহরণটি স্থির করেছি। খুশি হ'ল যদিও আপনি নিজেরাই এটি আবিষ্কার করেছেন।
বেনআলাবাস্টার

28
এই উত্তরটি যদি সঠিকভাবে লিঙ্ক-টু-এসকিউএল বা লিনক সম্পর্কে হত তবে এই উত্তরটি সঠিক হতে পারে। তবে, যেহেতু এটি নির্দিষ্টভাবে "লিনাক-টু-সত্তা" বলেছে তাই এই উত্তরটি ভুল। অ্যারে.কন্টেইনগুলি (এখনও) লিনক-টু-সত্তা দ্বারা সমর্থিত নয়।
ক্রিস্টোফেরায়

6
@ ক্রিস্টোফেরএ - এটি ইএফ-র পূর্ববর্তী সংস্করণগুলির ক্ষেত্রে সত্য হতে পারে তবে ইএফ 4 দিয়ে আমার পক্ষে এটি ঠিক আছে।
ড্রয় নোকস

21

এটি আপনার উদ্দেশ্যটি যথেষ্ট should এটি দুটি সংগ্রহের তুলনা করে এবং চেকগুলি তুলনা করে যদি একটি সংগ্রহে অন্য সংগ্রহের সাথে মানগুলির সাথে মিল রয়েছে

fea_Features.Where(s => selectedFeatures.Contains(s.feaId))

9

আপনি যদি VS2008 / .NET 3.5 ব্যবহার করেন তবে অ্যালেক্স জেমসের টিপ # 8 দেখুন: http://blogs.msdn.com/alexj/archive/2009/03/26/tip-8-writing-where-in-style -queries-ব্যবহার-linq টু entities.aspx

অন্যথায় কেবল অ্যারে ব্যবহার করুন ont


দয়া করে কেবলমাত্র লিঙ্কযুক্ত উত্তরগুলি এড়িয়ে চলুন, ভবিষ্যতে লিঙ্কটি ভাঙার ক্ষেত্রে আপনার উত্তরটিতে লিঙ্কের বিষয়বস্তুগুলি সংক্ষিপ্ত করে নেওয়া উচিত।


8

আমি এই প্রসঙ্গে ইনার জয়েনের পক্ষে যাব। আমি যদি এতে ব্যবহার করে থাকি তবে এটি মাত্র একটি ম্যাচ আছে তা সত্ত্বেও এটি 6 বার পুনরাবৃত্তি হবে।

var desiredNames = new[] { "Pankaj", "Garg" }; 

var people = new[]  
{  
    new { FirstName="Pankaj", Surname="Garg" },  
    new { FirstName="Marc", Surname="Gravell" },  
    new { FirstName="Jeff", Surname="Atwood" }  
}; 

var records = (from p in people join filtered in desiredNames on p.FirstName equals filtered  select p.FirstName).ToList(); 

ধারণগুলি অসুবিধা

ধরুন আমার কাছে দুটি তালিকার অবজেক্ট রয়েছে।

List 1      List 2
  1           12
  2            7
  3            8
  4           98
  5            9
  6           10
  7            6

কন্টেনস ব্যবহার করে, এটি তালিকা 2 এর প্রতিটি তালিকা 1 আইটেম অনুসন্ধান করবে যার অর্থ পুনরাবৃত্তি 49 বার ঘটবে !!!


5
এটি বিবৃতিটি এসকিউএল অনুবাদ করা হয়েছে তা সম্পূর্ণ উপেক্ষা করে। এখানে দেখুন ।
গার্ট আর্নল্ড

5

এটি সম্ভাব্য উপায় হতে পারে যেখানে আপনি ক্লজটিতে পরীক্ষা করতে সরাসরি লিনকিউ এক্সটেনশন পদ্ধতি ব্যবহার করতে পারেন

var result = _db.Companies.Where(c => _db.CurrentSessionVariableDetails.Select(s => s.CompanyId).Contains(c.Id)).ToList();

2

আমি একটি এসকিউএল-ইন-জাতীয় জিনিসটির সাথেও কাজ করার চেষ্টা করেছি - একটি সত্তা ডেটা মডেলের বিরুদ্ধে জিজ্ঞাসা করছি । আমার পদ্ধতির একটি বড় OR- এক্সপ্রেশন রচনা করার জন্য একটি স্ট্রিং নির্মাতা। এটি ভয়াবহভাবে কুৎসিত, তবে আমি এখনই একমাত্র উপায় হওয়ার ভয় করি।

এখন ভাল, এটি দেখতে দেখতে:

Queue<Guid> productIds = new Queue<Guid>(Products.Select(p => p.Key));
if(productIds.Count > 0)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendFormat("{0}.ProductId = Guid\'{1}\'", entities.Products.Name, productIds.Dequeue());
    while(productIds.Count > 0)
    {
        sb.AppendFormat(" OR {0}.ProductId = Guid\'{1}\'",
          entities.Products.Name, productIds.Dequeue());
    }
}

এই প্রসঙ্গে জিইউইউডির সাথে কাজ করা : আপনি উপরের মতো দেখতে পাচ্ছেন, কোয়েরি স্ট্রিংয়ের খণ্ডগুলিতে স্বয়ংক্রিয়ভাবে জিইউইডি-র আগে "জিইউডি" শব্দটি রয়েছে। আপনি যদি এটি যোগ না করেন তবে ObjectQuery<T>.Whereনিম্নলিখিত ব্যতিক্রম ছোঁড়ে:

'Edm.Guid' এবং 'Edm.String' আর্গুমেন্টের ধরণগুলি এই অপারেশনের জন্য বেমানান।, সমান অভিব্যক্তির নিকটে, লাইন 6, কলাম 14।

এটি এমএসডিএন ফোরামে পাওয়া গেছে, এটি মনে রাখতে সহায়ক হতে পারে।

ম্যাথিয়াস

... NET এবং সত্তা ফ্রেমওয়ার্কের পরবর্তী সংস্করণটির জন্য অপেক্ষা করছি, যখন সবকিছু ভাল হয়। :)


2

বেনআলাবাস্টারের উত্তরের একটি বিকল্প পদ্ধতি

প্রথমত, আপনি কোয়েরিটি আবার লিখতে পারেন:

var matches = from Users in people
        where Users.User_Rights == "Admin" ||
              Users.User_Rights == "Users" || 
              Users.User_Rights == "Limited"
        select Users;

অবশ্যই এটি আরও 'শব্দযুক্ত' এবং লেখার জন্য একটি ব্যথা তবে এটি একই রকম কাজ করে।

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

জায়গায় একটি ইউটিলিটি পদ্ধতিতে আপনি এই জাতীয় কিছু লিখতে পারেন:

var matches = ctx.People.Where(
        BuildOrExpression<People, string>(
           p => p.User_Rights, names
        )
);

এটি এমন একটি অভিব্যক্তি তৈরি করে যা এর মতো একই প্রভাব ফেলে:

var matches = from p in ctx.People
        where names.Contains(p.User_Rights)
        select p;

তবে এটি আরও গুরুত্বপূর্ণভাবে কাজ করে। নেট 3.5 এসপি 1 এর বিপরীতে।

এখানে নদীর গভীরতানির্ণয় কার্যটি এটি সম্ভব করে তোলে:

public static Expression<Func<TElement, bool>> BuildOrExpression<TElement, TValue>(
        Expression<Func<TElement, TValue>> valueSelector, 
        IEnumerable<TValue> values
    )
{     
    if (null == valueSelector) 
        throw new ArgumentNullException("valueSelector");

    if (null == values)
        throw new ArgumentNullException("values");  

    ParameterExpression p = valueSelector.Parameters.Single();

    if (!values.Any())   
        return e => false;

    var equals = values.Select(value =>
        (Expression)Expression.Equal(
             valueSelector.Body,
             Expression.Constant(
                 value,
                 typeof(TValue)
             )
        )
    );
   var body = equals.Aggregate<Expression>(
            (accumulate, equal) => Expression.Or(accumulate, equal)
    ); 

   return Expression.Lambda<Func<TElement, bool>>(body, p);
}

আমি এই পদ্ধতিটি ব্যাখ্যা করার চেষ্টা করতে যাচ্ছি না, অন্যটি বলার অপেক্ষা রাখে না যে এটি মূলত ভ্যালু সিলেক্টর (অর্থাত্ পি => পি। সূত্রের বিধেয়

সূত্র: http://blogs.msdn.com/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-used-linq-to-entities.aspx


0

বাস্তব উদাহরণ:

var trackList = Model.TrackingHistory.GroupBy(x => x.ShipmentStatusId).Select(x => x.Last()).Reverse();
List<int> done_step1 = new List<int>() {2,3,4,5,6,7,8,9,10,11,14,18,21,22,23,24,25,26 };
bool isExists = trackList.Where(x => done_step1.Contains(x.ShipmentStatusId.Value)).FirstOrDefault() != null;

-13

সিরিয়াসলি? আপনি লোকেরা কখনও ব্যবহার করেন নি

where (t.MyTableId == 1 || t.MyTableId == 2 || t.MyTableId == 3)

9
-1 1000 টিরও বেশি সারি সহ একটি টেবিলে 20 বা ততোধিক মান সহ এটি ব্যবহার করে দেখুন এবং আপনি দ্রুত গৃহীত সমাধানটির সুবিধা দেখতে পাবেন। এছাড়াও, যেখানে বিবৃতিটিতে একটি নির্বিচার সংখ্যক শর্তাদি যুক্ত করা সহজ নয় (যেমন ব্যবহারকারী যদি বিকল্প 1 এবং 2 অন্তর্ভুক্ত করতে বেছে নিচ্ছেন তবে 3 নয়)।
ট্রাইপড

ওয়েল, আমার কোনও পাগল বিজ্ঞানীর স্টাফের দরকার নেই এবং এই উত্তরটি আমার ভোটে যেতে পারে কারণ আমার একটি এবং 2 ওআরএস ভরা নমুনা পয়েন্টস দরকার ছিল (_ সিড থেকে _db.tblPWS_WSF_SPID_ISN_Lookup.OrderBy (x => x.WSFStateCode) যেখানে সি। পিডব্লিউএস == আইডি এবং& ((সি। ডাব্লুএসএফএসটিটকোড.সুবস্ট্রিং (0, 2) == "এসআর") || (c.WSFStateCode.Substring (0, 2) == "সিএইচ")) সি সিলেক্ট করুন () ;
জাস্টজাহন

@ ট্রাইপড - সারিগুলির সংখ্যা (1000) কোনও পরিবর্তন করে না - অথবা আমি কি কিছু মিস করছি?
tymtam

@ শব্দের সংক্ষেপ হ্যাঁ, সারিগুলির সংখ্যা গুরুত্বপূর্ণ। আরও সারি, আরও গণনা। সম্ভাব্য মান সংখ্যা সঙ্গে একই: Checks = NumValues * NumRows। কারণ এটি একটি এম * এন টাইপ গণনা, যদি হয় তবে তা যদি ছোট হয় তবে প্রতিটি প্রয়োজনীয় চেক সম্পাদনের সময়ও কম হবে। আমি সীমাবদ্ধতাটি যোগ করেছি তাই সিজেএম 30305 কীভাবে একটি পরীক্ষার পরিবেশ নির্ধারণ করতে পারে যেখানে তার সমাধানটি কেন দুর্বল তা দেখানো হবে।
18:58

@ ট্রিপড আপনি কি বলছেন যে where new[] { 1, 2, 3 }.Contains(x)তখন তুলনা কম হয় where (x == 1 || x == 2 || x == 3)?
tymtam
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.