আপনি কীভাবে লিনকিউয়ের সাথে "ইন না" প্রশ্নটি করবেন?


307

আমার দুটি সংগ্রহ রয়েছে যার দুটি সংকলনেই সম্পত্তি আছে Email। আমার প্রথম তালিকার আইটেমগুলির একটি তালিকা পাওয়া দরকার যেখানে Emailদ্বিতীয় তালিকায় নেই। এসকিউএল দিয়ে আমি কেবল "ইন ইন" ব্যবহার করব না, তবে আমি লিনকুতে এর সমতুল্য জানি না। কীভাবে হয়?

এখনও অবধি আমার একটি যোগদান হয়েছে, ...

var matches = from item1 in list1
join item2 in list2 on item1.Email equals item2.Email
select new { Email = list1.Email };

তবে আমি যোগদান করতে পারছি না কারণ আমার পার্থক্যের প্রয়োজন এবং যোগদানটি ব্যর্থ হবে। আমার বিশ্বাসযোগ্য কনটেইনস বা অস্তিত্বের ব্যবহারের কিছু উপায় আমার প্রয়োজন। আমি এখনও এটি করতে একটি উদাহরণ খুঁজে পাই নি।


3
দয়া করে নোট করুন যে ইকোস্টর্মের উত্তরটি এমন কোড তৈরি করে যা রবার্টের থেকে পড়ার চেয়ে স্পষ্ট
নাথান কোপ

উত্তর:


302

আমি জানি না এটি আপনাকে সাহায্য করবে কিনা তবে ..

NorthwindDataContext dc = new NorthwindDataContext();    
dc.Log = Console.Out;

var query =    
    from c in dc.Customers    
    where !(from o in dc.Orders    
            select o.CustomerID)    
           .Contains(c.CustomerID)    
    select c;

foreach (var c in query) Console.WriteLine( c );

থেকে LINQ মধ্যে না দফা এসকিউএল দ্বারা মার্কো রাসো


তবে আমি সত্তাগুলিতে লিনাক ব্যবহার করি, তাই আমি "কেবলমাত্র প্রাথমিক প্রকারগুলি ত্রুটি ব্যবহার করা যেতে পারে" পেয়েছি। আশেপাশে কোন কাজ আছে ...? ম্যানুয়ালি পুনরাবৃত্তি করা এবং তালিকাটি সন্ধান করা ছাড়াও।
শিক্ষানবিশ

13
এটি লিনকিউ থেকে সত্তার সাথে আমার পক্ষে দুর্দান্ত কাজ করে। এসকিউএল একটি সম্পূর্ণ নয় (কোয়ালিটি কোয়েরি) কোয়েরিতে পরিণত হয়। হতে পারে এমন কোনও আপডেট ছিল যা এটি সম্বোধন করেছিল?
স্কটিথেল

2
আমি মনে করি EF এর নতুন সংস্করণগুলি সমর্থন করে Cআপনি এই প্রশ্নটি EF (সংস্করণ) বা লিনকটোসকিউএল ট্যাগ করে না .. সুতরাং এখানে প্রশ্ন এবং উত্তর দেওয়ার সুযোগ থাকতে পারে ..
ব্রেট ক্যাসওয়েল

4
@ রবার্ট রাউস - লিঙ্কে নোট ইন ক্লজ থেকে এসকিউএল এর লিঙ্কটি আর কাজ করে না। শুধু একটি fyi।
জোনএইচ

সরবরাহ করা লিঙ্কটি কোনও সাইটকে ম্যালওয়্যারযুক্ত হিসাবে পতাকাঙ্কিত করে।
মাইকসিগ

334

আপনি বাদে অপারেটর চান।

var answer = list1.Except(list2);

এখানে আরও ভাল ব্যাখ্যা: https://docs.microsoft.com/archive/blogs/charlie/linq-farm-more-on-set-operators

দ্রষ্টব্য: জটিল কৌশল সহ পদ্ধতিটি ব্যবহার করার জন্য আপনাকে একটি আইক্যুলিটি কম্পায়ার প্রয়োগ করতে হবে, কারণ এই কৌশলটি কেবল আদিম ধরণের জন্য সর্বোত্তম কাজ করে Except


7
ব্যতীত ব্যবহার: আপনি যদি জটিল ধরণের তালিকাগুলি নিয়ে কাজ করেন তবে আপনাকে একটি আইকোয়ালিটি কম্পারার <মাইকম্প্লেক্স টাইপ> প্রয়োগ করতে হবে, এটি এটি এত সুন্দর করে না
সাকিতো

4
আপনি না আছে IEqualityComparer <টি> বাস্তবায়ন যদি আপনি শুধু রেফারেন্স সমতা তুলনা করতে চান অথবা আপনি উপেক্ষিত T.Equals থাকেন তাহলে () এবং T.GetHashCode ()। আপনি যদি IEqualityComparer <T>, EqualityComparer <T> প্রয়োগ না করেন তবে ডিফল্ট ব্যবহার করা হবে।
পাইদার

2
@ ইকোস্টর্ম (এবং অন্যরা পড়ছেন), আপনি যদি একটি বেনামে থাকা বস্তুতে নির্বাচন করেন, হ্যাশকোড সম্পত্তি মান দ্বারা নির্ধারিত হবে; list1.Select(item => new { Property1 = item.Property1, Property2 = item.Property2 }).Except(list2.Select( item => new { Property1 = item.Property1, Property2 = item.Property2 }));আপনি জটিল ধরণের মানগুলির একটি সেটকে মূল্যায়ন করে সমতা নির্ধারণ করার সময় এটি বিশেষ কার্যকর useful
ব্রেট ক্যাসওয়েল

3
প্রকৃতপক্ষে, কেউ নীচে নির্দেশ করেছেন এবং আমি সঠিকভাবে মনে করি, কোনও IEquatityComparor<T,T>দৃশ্যে অবজেক্টের তুলনা পদ্ধতিগুলি প্রয়োগ বা ওভাররাইড করার প্রয়োজন হবে না LinqToSql; কারণ, ক্যোয়ারী এসকিউএল হিসাবে সংকলিত / প্রকাশিত হিসাবে উপস্থাপিত হবে; সুতরাং মানগুলি পরীক্ষা করা হবে, বস্তুর রেফারেন্স নয়।
ব্রেট ক্যাসওয়েল

2
exceptআমি ব্যবহার করে আমি একটি লিনকিউ ক্যোয়ারীটি 8-10 সেকেন্ড থেকে অর্ধেক সেকেন্ডে গতি অর্জন করতে সক্ষম হয়েছি
মাইকেল কিনিস্কার্ন

61

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

var itemIds = inMemoryList.Select(x => x.Id).ToArray();
var otherObjects = context.ItemList.Where(x => !itemIds.Contains(x.Id));

এটি WHERE ... IN (...)এসকিউএলে একটি দুর্দান্ত ধারা তৈরি করে ।


1
প্রকৃতপক্ষে, আপনি এটি 3.5 তে করতে পারেন
জর্জ সিলভা

59

প্রথম তালিকার আইটেমগুলি যেখানে ইমেলটি দ্বিতীয় তালিকায় নেই।

from item1 in List1
where !(list2.Any(item2 => item2.Email == item1.Email))
select item1;

16

খুঁজে না পাওয়ার জন্য আপনি কোথায় এবং যে কোনওটির সংমিশ্রণটি ব্যবহার করতে পারেন:

var NotInRecord =list1.Where(p => !list2.Any(p2 => p2.Email  == p.Email));

8

আপনি দুটি সংগ্রহ দুটি ভিন্ন তালিকায় নিতে পারেন, তালিকা 1 এবং তালিকা 2 বলুন।

তারপর শুধু লিখুন

list1.RemoveAll(Item => list2.Contains(Item));

এটি কাজ করবে।


3
তালিকা থেকে উপাদানগুলি সরানোর জন্য দুর্দান্ত তবে এর পার্শ্ব প্রতিক্রিয়া রয়েছে।
তারিক

7

যে কোনও ক্ষেত্রে ADO.NET সত্তা ফ্রেমওয়ার্ক ব্যবহার করা হচ্ছে , ইকোস্টোর্মের সমাধানও পুরোপুরি কার্যকরভাবে কাজ করে। তবে আমার মাথাটি চারপাশে মুড়ে নিতে কয়েক মিনিট সময় লাগল। ধরে নিই আপনার কাছে একটি ডাটাবেস প্রসঙ্গ আছে, ডিসি, এবং টেবিলের সাথে সারণি x সারণি x এ সংযুক্ত নয় সন্ধান করতে চান, সম্পূর্ণ উত্তরের উত্তরটি দেখে মনে হচ্ছে:

var linked =
  from x in dc.X
  from y in dc.Y
  where x.MyProperty == y.MyProperty
  select x;
var notLinked =
  dc.X.Except(linked);

অ্যান্ডির মন্তব্যের জবাবে, হ্যাঁ, একটি লিনকুই ক্যোয়ারিতে একজনের কাছ থেকে দু'জন থাকতে পারে। তালিকাগুলি ব্যবহার করে এখানে একটি সম্পূর্ণ কাজের উদাহরণ। প্রতিটি ক্লাস, ফু এবং বারের একটি আইডি থাকে। Foo.BarId এর মাধ্যমে বারের কাছে ফু'র একটি "বিদেশী কী" উল্লেখ রয়েছে। প্রোগ্রামটি সমস্ত ফুগুলি সম্পর্কিত বারের সাথে লিঙ্কযুক্ত না বাছাই করে।

class Program
{
    static void Main(string[] args)
    {
        // Creates some foos
        List<Foo> fooList = new List<Foo>();
        fooList.Add(new Foo { Id = 1, BarId = 11 });
        fooList.Add(new Foo { Id = 2, BarId = 12 });
        fooList.Add(new Foo { Id = 3, BarId = 13 });
        fooList.Add(new Foo { Id = 4, BarId = 14 });
        fooList.Add(new Foo { Id = 5, BarId = -1 });
        fooList.Add(new Foo { Id = 6, BarId = -1 });
        fooList.Add(new Foo { Id = 7, BarId = -1 });

        // Create some bars
        List<Bar> barList = new List<Bar>();
        barList.Add(new Bar { Id = 11 });
        barList.Add(new Bar { Id = 12 });
        barList.Add(new Bar { Id = 13 });
        barList.Add(new Bar { Id = 14 });
        barList.Add(new Bar { Id = 15 });
        barList.Add(new Bar { Id = 16 });
        barList.Add(new Bar { Id = 17 });

        var linked = from foo in fooList
                     from bar in barList
                     where foo.BarId == bar.Id
                     select foo;
        var notLinked = fooList.Except(linked);
        foreach (Foo item in notLinked)
        {
            Console.WriteLine(
                String.Format(
                "Foo.Id: {0} | Bar.Id: {1}",
                item.Id, item.BarId));
        }
        Console.WriteLine("Any key to continue...");
        Console.ReadKey();
    }
}

class Foo
{
    public int Id { get; set; }
    public int BarId { get; set; }
}

class Bar
{
    public int Id { get; set; }
}

লিনকুতে দু'জন বোধহয় পড়ে? এটা সহায়ক হবে।
অ্যান্ডি

অ্যান্ডি: হ্যাঁ, উপরে সংশোধিত উত্তর দেখুন।
ব্রেট

4
var secondEmails = (from item in list2
                    select new { Email = item.Email }
                   ).ToList();

var matches = from item in list1
              where !secondEmails.Contains(item.Email)
              select new {Email = item.Email};


2

যদিও Exceptউত্তরের অংশ, এটি সম্পূর্ণ উত্তর নয়। ডিফল্টরূপে Except(লিনকিউ অপারেটরের বেশ কয়েকটি) রেফারেন্সের ধরণের তুলনায় একটি রেফারেন্স তুলনা করে। বস্তুগুলির মানগুলির সাথে তুলনা করতে আপনাকে করতে হবে

  • বাস্তবায়ন IEquatable<T>আপনার প্রকারে করুন, বা
  • ওভাররাইড EqualsএবংGetHashCode আপনার টাইপ, বা
  • IEqualityComparer<T>আপনার টাইপের জন্য প্রযোজ্য কোনও প্রকারের উদাহরণটি পাস করুন

2
... যদি আমরা অবজেক্টগুলিতে লিনকিউ সম্পর্কে কথা বলি। যদি এটি এসকিউএল-এর লিনকুই ছিল, কোয়েরিটি এসকিউএল বিবৃতিতে অনুবাদ করা হয়েছে যা ডাটাবেসে চালিত হয়, সুতরাং এটি প্রযোজ্য নয়।
লুকাস 21

1

সরলতার জন্য ইন্টের তালিকা ব্যবহার করে উদাহরণ।

List<int> list1 = new List<int>();
// fill data
List<int> list2 = new List<int>();
// fill data

var results = from i in list1
              where !list2.Contains(i)
              select i;

foreach (var result in results)
    Console.WriteLine(result.ToString());

1

যে কেউ INসি # তে এসকিউএল-এলাইক অপারেটরটি ব্যবহার করতে চান তাদের জন্য এই প্যাকেজটি ডাউনলোড করুন:

Mshwf.NiceLinq

এটির Inএবং NotInপদ্ধতিগুলি:

var result = list1.In(x => x.Email, list2.Select(z => z.Email));

এমনকি আপনি এটি এইভাবে ব্যবহার করতে পারেন

var result = list1.In(x => x.Email, "a@b.com", "b@c.com", "c@d.com");

0

ধন্যবাদ, ব্রেট আপনার পরামর্শ আমাকে খুব সাহায্য করেছে। আমার কাছে অবজেক্টগুলির একটি তালিকা ছিল এবং আমি ফিল্টার করতে চেয়েছিলাম অন্য বস্তুর তালিকা ব্যবহার করে। আবার ধন্যবাদ....

কারও যদি প্রয়োজন হয় তবে দয়া করে আমার কোডের নমুনাটি দেখুন:

'First, get all the items present in the local branch database
Dim _AllItems As List(Of LocalItem) = getAllItemsAtBranch(BranchId, RecordState.All)

'Then get the Item Mappings Present for the branch
Dim _adpt As New gItem_BranchesTableAdapter
Dim dt As New ds_CA_HO.gItem_BranchesDataTable
    _adpt.FillBranchMappings(dt, BranchId)

Dim _MappedItems As List(Of LocalItem) = (From _item As LocalItem In _AllItems Join _
    dr As ds_CA_HO.gItem_BranchesRow In dt _
    On _item.Id Equals dr.numItemID _
    Select _item).ToList

_AllItems = _AllItems.Except(_MappedItems.AsEnumerable).ToList

 Return _AllItems

0

আমি লিনকিউ থেকে সত্তা থেকে এটি পরীক্ষা করিনি :

NorthwindDataContext dc = new NorthwindDataContext();    
dc.Log = Console.Out;

var query =    
    from c in dc.Customers 
    where !dc.Orders.Any(o => o.CustomerID == c.CustomerID)   
    select c;

বিকল্পভাবে:

NorthwindDataContext dc = new NorthwindDataContext();    
dc.Log = Console.Out;

var query =    
    from c in dc.Customers 
    where dc.Orders.All(o => o.CustomerID != c.CustomerID)   
    select c;

foreach (var c in query) 
    Console.WriteLine( c );

0

গোষ্ঠীটি খালি থাকলে কেবল প্রথম তালিকা থেকে আইটেমগুলি নির্বাচন করে আপনি কি কোনও বাহ্যিক যোগদান করতে পারবেন না? কিছুটা এইরকম:

Dim result = (From a In list1
              Group Join b In list2 
                  On a.Value Equals b.Value 
                  Into grp = Group
              Where Not grp.Any
              Select a)

সত্তা ফ্রেমওয়ার্কের সাথে এটি কোনও ধরণের দক্ষ পদ্ধতিতে কাজ করবে কিনা তা সম্পর্কে আমি নিশ্চিত নই।


0

বিকল্পভাবে আপনি এটি করতে পারেন:

var result = list1.Where(p => list2.All(x => x.Id != p.Id));
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.