লিঙ্কে বাম আউটরের যোগদান করুন


538

join-on-equals-intoধারাগুলি ব্যবহার না করে কীভাবে সি # লিনকুতে বাম বাহিরের জোড় পরিবেশন করবেন ? whereদফা দিয়ে তা করার কোনও উপায় আছে কি ? সঠিক সমস্যা: অভ্যন্তরীণ যোগদানের জন্য সহজ এবং আমার মতো সমাধান রয়েছে

List<JoinPair> innerFinal = (from l in lefts from r in rights where l.Key == r.Key
                             select new JoinPair { LeftId = l.Id, RightId = r.Id})

তবে বাম বাহিরের যোগদানের জন্য আমার একটি সমাধান দরকার। আমার এইরকম কিছু তবে এটি কাজ করছে না

List< JoinPair> leftFinal = (from l in lefts from r in rights
                             select new JoinPair { 
                                            LeftId = l.Id, 
                                            RightId = ((l.Key==r.Key) ? r.Id : 0
                                        })

যেখানে জয়েন পেয়ার একটি ক্লাস:

public class JoinPair { long leftId; long rightId; }

2
আপনি যা অর্জন করার চেষ্টা করছেন তার উদাহরণ দিতে পারেন?
jeroenh

সাধারণ বাম বাহ্যিক জোড় কিছু হ'ল: var a = b থেকে bb join c সি সি সি সি সি সি সি সি সমান হয়ে ডিডি থেকে ডিডি-ডিফল্টআইফএম্পটি () সিলেক্ট করুন বি.এসএসএস; আমার প্রশ্নটি যে জোড়-অন-সমতুল্য-তে ক্লোস ব্যবহার করে কিছু করতে পারে তা এইরকম a = b থেকে bb থেকে bc থেকে cc তে যেখানে b.bbb == c.cccc ... এবং আরও কিছু আছে .. ।
খেলনা

1
অবশ্যই আছে তবে আপনার কোডটির উদাহরণ ইতিমধ্যে আপনার পোস্ট করা উচিত যাতে লোকেরা আপনাকে আরও ভাল উত্তর দিতে পারে
oth

আমি একটি "বামকে বাদ দিয়ে " জয়িনের সন্ধান করছিলাম (এবং আমি এটি "আউটার" ধারণাটি দিয়ে বিভ্রান্ত করেছি)। এই উত্তরটি আমি যা চেয়েছিলাম তার কাছাকাছি ছিল।
রেড মটর

উত্তর:


597

যেমন বলা হয়েছে:

101 লিনিকের নমুনা - বাম বাহিরের জোড়

var q =
    from c in categories
    join p in products on c.Category equals p.Category into ps
    from p in ps.DefaultIfEmpty()
    select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName };

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

3
@ জেইন আপনার প্রকারের ধরনগুলি আলাদা হলে যোগদান কাজ করবে না। সুতরাং সম্ভবত আপনার কীগুলি বিভিন্ন ডেটাটাইপগুলির। উভয় কী কী উদাহরণস্বরূপ?
Yooakim

2
কী সমাধান জৈন? আমিও একই ত্রুটির মুখোমুখি হয়েছি এবং প্রকারগুলিও আমার ক্ষেত্রে একই।
সন্দীপ

1
@ সন্দীপ আপনার কীগুলি আপনি এতে যোগদান করেছেন তা পরীক্ষা করুন। ধরুন সেগুলি যদি স্ট্রিং এবং ইন্টের ধরণের হয় তবে স্ট্রিং কীকে কেবল ইনটে রূপান্তর করুন।
অঙ্কিত


546

যদি লিনকিউ সরবরাহকারী একটি ডাটাবেস ব্যবহার করা হয় তবে উল্লেখযোগ্যভাবে আরও পঠনযোগ্য বাম বাহ্যিক জোড়টি এমনভাবে লেখা যেতে পারে:

from maintable in Repo.T_Whatever 
from xxx in Repo.T_ANY_TABLE.Where(join condition).DefaultIfEmpty()

আপনি বাদ DefaultIfEmpty()দিলে আপনার অভ্যন্তরীণ যোগদান হবে।

গৃহীত উত্তর নিন:

  from c in categories
    join p in products on c equals p.Category into ps
    from p in ps.DefaultIfEmpty()

এই বাক্য গঠনটি খুব বিভ্রান্তিকর, এবং আপনি বহু সারণিতে যোগদান করতে চাইলে এটি কীভাবে কাজ করে তা পরিষ্কার নয়।

দ্রষ্টব্য
এটি লক্ষ্য করা উচিত যে from alias in Repo.whatever.Where(condition).DefaultIfEmpty()বাহ্যিক প্রয়োগ / বাম-যোগ-পার্শ্বীয় হিসাবে একই, যে কোনও (শালীন) ডাটাবেস-অপ্টিমাইজার যতক্ষণ না আপনি প্রতি সারিটি প্রবর্তন করেন না ততক্ষণ বাম জোনে অনুবাদ করতে পুরোপুরি সক্ষম মূল্যগুলি (ওরফে একটি প্রকৃত বাইরের প্রয়োগ)। লিনক-টু-অবজেক্টে এটি করবেন না (কারণ আপনি লিনক-টু-অবজেক্ট ব্যবহার করার সময় কোনও ডিবি-অপ্টিমাইজার নেই)।

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

var query2 = (
    from users in Repo.T_User
    from mappings in Repo.T_User_Group
         .Where(mapping => mapping.USRGRP_USR == users.USR_ID)
         .DefaultIfEmpty() // <== makes join left join
    from groups in Repo.T_Group
         .Where(gruppe => gruppe.GRP_ID == mappings.USRGRP_GRP)
         .DefaultIfEmpty() // <== makes join left join

    // where users.USR_Name.Contains(keyword)
    // || mappings.USRGRP_USR.Equals(666)  
    // || mappings.USRGRP_USR == 666 
    // || groups.Name.Contains(keyword)

    select new
    {
         UserId = users.USR_ID
        ,UserName = users.USR_User
        ,UserGroupId = groups.ID
        ,GroupName = groups.Name
    }

);


var xy = (query2).ToList();

লিনকিউ 2 এসকিউএল-এর সাথে ব্যবহার করা হলে এটি নিম্নলিখিত খুব সুস্পষ্ট এসকিউএল কোয়েরিতে সুন্দরভাবে অনুবাদ করবে:

SELECT 
     users.USR_ID AS UserId 
    ,users.USR_User AS UserName 
    ,groups.ID AS UserGroupId 
    ,groups.Name AS GroupName 
FROM T_User AS users

LEFT JOIN T_User_Group AS mappings
   ON mappings.USRGRP_USR = users.USR_ID

LEFT JOIN T_Group AS groups
    ON groups.GRP_ID == mappings.USRGRP_GRP

সম্পাদনা:

আরও জটিল উদাহরণের জন্য "লিঙ্ক ক্যোয়ারিতে এসকিউএল সার্ভারের ক্যোয়ারিতে রূপান্তর করুন " দেখুন ।

এছাড়াও, আপনি যদি এটি লিনাক-২-অবজেক্টগুলিতে (লিনক -২-এসকিউএল এর পরিবর্তে) করছেন, আপনার এটি পুরানো পদ্ধতিতে করা উচিত (কারণ লিনকিউ থেকে এসকিউএল এটি অপারেশনগুলিতে যোগদানের জন্য এটি সঠিকভাবে অনুবাদ করে, তবে বস্তুগুলির উপরে এই পদ্ধতিটি ব্যবহার করে) একটি পূর্ণ স্ক্যান করার জন্য জোর করে, এবং সূচী অনুসন্ধানগুলির সুবিধা গ্রহণ করবে না, কেন ...):

    var query2 = (
    from users in Repo.T_Benutzer
    join mappings in Repo.T_Benutzer_Benutzergruppen on mappings.BEBG_BE equals users.BE_ID into tmpMapp
    join groups in Repo.T_Benutzergruppen on groups.ID equals mappings.BEBG_BG into tmpGroups
    from mappings in tmpMapp.DefaultIfEmpty()
    from groups in tmpGroups.DefaultIfEmpty()
    select new
    {
         UserId = users.BE_ID
        ,UserName = users.BE_User
        ,UserGroupId = mappings.BEBG_BG
        ,GroupName = groups.Name
    }

);

21
এই উত্তরটি আসলে সহায়ক। প্রকৃতপক্ষে বোধগম্য সিনট্যাক্স সরবরাহ করার জন্য আপনাকে ধন্যবাদ।
ক্রিস মেরিসিক

3
ডাব্লুটিবি একটি এনহাইবারনেট সামঞ্জস্যযুক্ত লিনকিউ ক্যোয়ারী ... :)
এমএক্সমিসাইল

30
লিনকিউ থেকে এসকিউএল অপারেশনগুলিতে যোগদানের জন্য এটি সঠিকভাবে অনুবাদ করে। যাইহোক অবজেক্টগুলির ওপরে এই পদ্ধতিটি একটি সম্পূর্ণ স্ক্যানকে জোর করে, এই কারণেই অফিসিয়াল ডকুমেন্টেশনগুলি গোষ্ঠীটিতে যোগ দেওয়ার সমাধান সরবরাহ করে যা সূচী অনুসন্ধানগুলিতে হ্যাশগুলির সুবিধা নিতে পারে।
তামির ড্যানিয়েলি

3
আমি মনে করি স্পষ্ট বাক্য গঠন প্রণালী joinআরো অনেক কিছু পাঠযোগ্য এবং পরিষ্কার একটি চেয়ে whereঅনুসৃত দ্বারাDefaultIfEmpty
FindOut_Quran

1
@ ব্যবহারকারী 3441905: যতক্ষণ না আপনি কেবল টেবিলের সাথে টেবিল বিতে যোগ দিতে হবে, এটি হতে পারে। তবে যত তাড়াতাড়ি আপনার চেয়ে বেশি কিছু হবে, তা হবে না। তবে মাত্র 2 টেবিলের জন্যও আমি মনে করি এটি অত্যধিক ভার্ভাস। জনপ্রিয় মতামতটিও আপনার বিরুদ্ধে বলে মনে হচ্ছে, যখন এই উত্তরটি 0 দিয়ে শুরু হয়েছিল যখন শীর্ষের উত্তরটিতে ইতিমধ্যে 90+ টি আপত্তি ছিল।
স্টেফান স্টেইগার

131

ল্যাম্বডা এক্সপ্রেশন ব্যবহার করে

db.Categories    
  .GroupJoin(db.Products,
      Category => Category.CategoryId,
      Product => Product.CategoryId,
      (x, y) => new { Category = x, Products = y })
  .SelectMany(
      xy => xy.Products.DefaultIfEmpty(),
      (x, y) => new { Category = x.Category, Product = y })
  .Select(s => new
  {
      CategoryName = s.Category.Name,     
      ProductName = s.Product.Name   
  });

8
যোগদান এবং গ্রুপজয়াইন উভয়ই বাম-যোগটিকে সত্যই সমর্থন করে না। গ্রুপজয়াইন ব্যবহারের কৌশলটি হ'ল আপনার খালি দল থাকতে পারে এবং তারপরে সেই খালি গোষ্ঠীগুলিকে খালি মানগুলিতে অনুবাদ করতে পারেন। Enumerable.Empty<Product>.DefaultIfEmpty()DefaultIfEmpty কেবল এটাই করে, অর্থটির একক মান সহ একটি মূল সংখ্যা ফিরে আসবে default(Product)
তামির ড্যানিয়েলি

61
এই সমস্ত একটি বাম যোগদান করতে ??
FindOut_Quran

7
এর জন্য ধন্যবাদ! খুব বেশি ল্যাম্বডা এক্সপ্রেশন উদাহরণ নেই, এটি আমার পক্ষে কাজ করেছে।
জোহান হেনকেনস

1
উত্তরের জন্য ধন্যবাদ. এটি কাঁচা এসকিউএল লেফট আউট জয়েন্টের নিকটতম জিনিসটি পেয়েছি যা আমি কয়েক বছর ধরে লিখেছি
জন গাথোগো

1
সত্যিই শেষ নির্বাচন () এর দরকার নেই, সিলেক্টম্যানির () সিলেক্টন অ্যানজোন একই আউটপুটটির জন্য রিফ্যাক্টর করা যেতে পারে। আরেকটি ধারণা হ'ল নিকটবর্তী বাম জোয়ার সমতুল্য অনুকরণ করার জন্য শূন্যতার জন্য y পরীক্ষা করা।
ডেনি জ্যাকব

46

এখন এক্সটেনশন পদ্ধতি হিসাবে:

public static class LinqExt
{
    public static IEnumerable<TResult> LeftOuterJoin<TLeft, TRight, TKey, TResult>(this IEnumerable<TLeft> left, IEnumerable<TRight> right, Func<TLeft, TKey> leftKey, Func<TRight, TKey> rightKey,
        Func<TLeft, TRight, TResult> result)
    {
        return left.GroupJoin(right, leftKey, rightKey, (l, r) => new { l, r })
             .SelectMany(
                 o => o.r.DefaultIfEmpty(),
                 (l, r) => new { lft= l.l, rght = r })
             .Select(o => result.Invoke(o.lft, o.rght));
    }
}

আপনি সাধারণত যোগদানের মতো ব্যবহার করুন:

var contents = list.LeftOuterJoin(list2, 
             l => l.country, 
             r => r.name,
            (l, r) => new { count = l.Count(), l.country, l.reason, r.people })

আশা করি এটি আপনার কিছুটা সময় সাশ্রয় করবে।


44

এই উদাহরণটি একবার দেখুন । এই ক্যোয়ারিতে কাজ করা উচিত:

var leftFinal = from left in lefts
                join right in rights on left equals right.Left into leftRights
                from leftRight in leftRights.DefaultIfEmpty()
                select new { LeftId = left.Id, RightId = left.Key==leftRight.Key ? leftRight.Id : 0 };

3
পারি rএকটি মধ্যে যোগদানের ব্যবহার করে পরে SELECT বাক্যাংশে অ্যাক্সেস করা যেতে?
ফরহাদ আলিজাদে নূরী

@ ফারহাদআলিজাদেহ নূরি হ্যাঁ এটি করতে পারে।
পো-টা-টু

লেখক সম্ভবত rদ্বিতীয় fromধারাটিতে পুনরায় ব্যবহার করতে চেয়েছিলেন । উদাহরণস্বরূপ from r in lrs.DefaultIfEmpty()অন্যথায় এই ক্যোয়ারীটি বেশি অর্থবোধ করে না এবং সম্ভবত rনির্বাচনের ক্ষেত্রে প্রসঙ্গের বাইরে থাকার কারণে সংকলনও করছে না ।
সায়েব আমিনী

@ দেবার্ট, আমি যখন আপনার জিজ্ঞাসাটি পড়ি তখন এটি আমাকে Clockwiseজন ক্লেিজের সাথে মুভিটির স্মরণ করিয়ে দেয় l
মাতাস ভাইটকেভিসিয়াস

1
বাম থেকে ডানদিকে বাম দিকে ডানদিকে বাম দিক থেকে ডানদিকে বাম দিক থেকে ... ওহ জিজ ... লিনিক-এ লেফট আউটয়ার জয়েন ব্যবহারের বাক্য গঠনটি প্রকৃতপক্ষে পরিষ্কার নয়, তবে এই নামগুলি সত্যই এটি আরও স্পষ্ট করে তোলে।
মাইক গ্লেডহিল

19

এক্সটেনশন পদ্ধতিগুলির দ্বারা বাম বাহিরের জোড়ার একটি বাস্তবায়ন দেখতে পারে

public static IEnumerable<Result> LeftJoin<TOuter, TInner, TKey, Result>(
  this IEnumerable<TOuter> outer, IEnumerable<TInner> inner
  , Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector
  , Func<TOuter, TInner, Result> resultSelector, IEqualityComparer<TKey> comparer)
  {
    if (outer == null)
      throw new ArgumentException("outer");

    if (inner == null)
      throw new ArgumentException("inner");

    if (outerKeySelector == null)
      throw new ArgumentException("outerKeySelector");

    if (innerKeySelector == null)
      throw new ArgumentException("innerKeySelector");

    if (resultSelector == null)
      throw new ArgumentException("resultSelector");

    return LeftJoinImpl(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer ?? EqualityComparer<TKey>.Default);
  }

  static IEnumerable<Result> LeftJoinImpl<TOuter, TInner, TKey, Result>(
      IEnumerable<TOuter> outer, IEnumerable<TInner> inner
      , Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector
      , Func<TOuter, TInner, Result> resultSelector, IEqualityComparer<TKey> comparer)
  {
    var innerLookup = inner.ToLookup(innerKeySelector, comparer);

    foreach (var outerElment in outer)
    {
      var outerKey = outerKeySelector(outerElment);
      var innerElements = innerLookup[outerKey];

      if (innerElements.Any())
        foreach (var innerElement in innerElements)
          yield return resultSelector(outerElment, innerElement);
      else
        yield return resultSelector(outerElment, default(TInner));
     }
   }

ফলাফল নির্বাচনের পরে নাল উপাদানগুলির যত্ন নিতে হবে। Fx।

   static void Main(string[] args)
   {
     var inner = new[] { Tuple.Create(1, "1"), Tuple.Create(2, "2"), Tuple.Create(3, "3") };
     var outer = new[] { Tuple.Create(1, "11"), Tuple.Create(2, "22") };

     var res = outer.LeftJoin(inner, item => item.Item1, item => item.Item1, (it1, it2) =>
     new { Key = it1.Item1, V1 = it1.Item2, V2 = it2 != null ? it2.Item2 : default(string) });

     foreach (var item in res)
       Console.WriteLine(string.Format("{0}, {1}, {2}", item.Key, item.V1, item.V2));
   }

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

13
তবে প্রশ্নটি ছিল " বস্তুগুলিতে সি # লিনকুতে কীভাবে বাম বাহ্যিক যোগদান সম্পাদন করা যায় ..."
বার্ট্র্যান্ড

12

এই উদাহরণটি দেখুন

class Person
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Phone { get; set; }
}

class Pet
{
    public string Name { get; set; }
    public Person Owner { get; set; }
}

public static void LeftOuterJoinExample()
{
    Person magnus = new Person {ID = 1, FirstName = "Magnus", LastName = "Hedlund"};
    Person terry = new Person {ID = 2, FirstName = "Terry", LastName = "Adams"};
    Person charlotte = new Person {ID = 3, FirstName = "Charlotte", LastName = "Weiss"};
    Person arlene = new Person {ID = 4, FirstName = "Arlene", LastName = "Huff"};

    Pet barley = new Pet {Name = "Barley", Owner = terry};
    Pet boots = new Pet {Name = "Boots", Owner = terry};
    Pet whiskers = new Pet {Name = "Whiskers", Owner = charlotte};
    Pet bluemoon = new Pet {Name = "Blue Moon", Owner = terry};
    Pet daisy = new Pet {Name = "Daisy", Owner = magnus};

    // Create two lists.
    List<Person> people = new List<Person> {magnus, terry, charlotte, arlene};
    List<Pet> pets = new List<Pet> {barley, boots, whiskers, bluemoon, daisy};

    var query = from person in people
        where person.ID == 4
        join pet in pets on person equals pet.Owner  into personpets
        from petOrNull in personpets.DefaultIfEmpty()
        select new { Person=person, Pet = petOrNull}; 



    foreach (var v in query )
    {
        Console.WriteLine("{0,-15}{1}", v.Person.FirstName + ":", (v.Pet == null ? "Does not Exist" : v.Pet.Name));
    }
}

// This code produces the following output:
//
// Magnus:        Daisy
// Terry:         Barley
// Terry:         Boots
// Terry:         Blue Moon
// Charlotte:     Whiskers
// Arlene:

এখন আপনি include elements from the leftযদি সেই উপাদানটি করতে সক্ষম হন তবে has no matches in the rightআমাদের ক্ষেত্রে আমরা পুনরুদ্ধার করেছিArlene এমনকি তার ডানদিকে কোনও মিল নেই

এখানে রেফারেন্স

কীভাবে: বাম বাহ্যায় যোগদান করে (সি # প্রোগ্রামিং গাইড)


আউটপুটটি হওয়া উচিত: আরলিন: অস্তিত্ব নেই
ব্যবহারকারী 1169587

10

এটি সাধারণ ফর্ম (যেমন ইতিমধ্যে অন্যান্য উত্তরে সরবরাহ করা হয়েছে)

var c =
    from a in alpha
    join b in beta on b.field1 equals a.field1 into b_temp
    from b_value in b_temp.DefaultIfEmpty()
    select new { Alpha = a, Beta = b_value };

তবে এখানে একটি ব্যাখ্যা যা আমি আশা করি যে এটির অর্থ কী তা পরিষ্কার হয়ে যাবে!

join b in beta on b.field1 equals a.field1 into b_temp

মূলত একটি পৃথক ফলাফল সেট b_temp তৈরি করে যা ডানদিকে প্রবেশের জন্য কার্যকরভাবে নাল 'সারি' অন্তর্ভুক্ত করে ('বি' তে প্রবেশ)।

তারপরে পরবর্তী লাইন:

from b_value in b_temp.DefaultIfEmpty()

.. ফলাফল ফলাফলের উপরে অঙ্কিত, ডানদিকে 'সারি' এর জন্য ডিফল্ট নাল মান নির্ধারণ করা এবং ডান হাতের সারিটির ফলাফল সেট করে 'b_value' (যেমন ডানদিকে থাকা মান) হাতের দিক, যদি কোনও মিল আছে রেকর্ড, বা 'নাল' না থাকলে)।

এখন, ডান পাশের অংশটি যদি একটি পৃথক লিনকুই কোয়েরির ফলাফল হয় তবে এটি বেনামে অন্তর্ভুক্ত থাকবে, যা কেবল 'কিছু' বা 'নাল' হতে পারে। যদি এটি একটি গণনামূলক তবে (যেমন একটি তালিকা - যেখানে MyObjectB 2 ক্ষেত্র সহ একটি শ্রেণি), তবে এর বৈশিষ্ট্যগুলির জন্য ডিফল্ট 'নাল' মানগুলি কী ব্যবহৃত হবে তা সম্পর্কে সুনির্দিষ্ট হওয়া সম্ভব:

var c =
    from a in alpha
    join b in beta on b.field1 equals a.field1 into b_temp
    from b_value in b_temp.DefaultIfEmpty( new MyObjectB { Field1 = String.Empty, Field2 = (DateTime?) null })
    select new { Alpha = a, Beta_field1 = b_value.Field1, Beta_field2 = b_value.Field2 };

এটি নিশ্চিত করে যে 'বি' নিজেই নাল নয় (তবে এর বৈশিষ্ট্যগুলি শূন্য হতে পারে, আপনার উল্লেখ করা ডিফল্ট নাল মানগুলি ব্যবহার করে) এবং এটি আপনাকে b_value এর জন্য নাল রেফারেন্স ব্যতিক্রম না পেয়ে b_value এর বৈশিষ্ট্যগুলি পরীক্ষা করতে দেয়। নোটযোগ্য তারিখের জন্য, একধরণের (ডেটটাইম?) অর্থাত্ 'nullable DateTime' অবশ্যই 'DefaultIfEmpty' এর জন্য স্পেসিফিকেশনের নলের 'প্রকার' হিসাবে নির্দিষ্ট করা আবশ্যক (এটি সেই জাতীয় প্রকারের ক্ষেত্রেও প্রযোজ্য যা 'স্থানীয়ভাবে নয়' 'নুলযোগ্য যেমন ডাবল, ভাসা)।

আপনি কেবল উপরের সিনট্যাক্সটি শৃঙ্খলাবদ্ধ করে একাধিক বাম বাহ্যিক বাহিরে যোগদান করতে পারেন।


1
বি_ভ্যালু কোথা থেকে আসে?
জ্যাক ফ্রেজার

9

আপনার যদি 2 টিরও বেশি টেবিলগুলিতে যোগদান করতে হয় তবে একটি উদাহরণ এখানে দিন:

from d in context.dc_tpatient_bookingd
join bookingm in context.dc_tpatient_bookingm 
     on d.bookingid equals bookingm.bookingid into bookingmGroup
from m in bookingmGroup.DefaultIfEmpty()
join patient in dc_tpatient
     on m.prid equals patient.prid into patientGroup
from p in patientGroup.DefaultIfEmpty()

রেফ: https://stackoverflow.com/a/17142392/2343


4

জোড় সিনট্যাক্সের সাথে বাম জোড়ার মতো কাজ করে এমন বর্ধন পদ্ধতি

public static class LinQExtensions
{
    public static IEnumerable<TResult> LeftJoin<TOuter, TInner, TKey, TResult>(
        this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, 
        Func<TOuter, TKey> outerKeySelector, 
        Func<TInner, TKey> innerKeySelector, 
        Func<TOuter, TInner, TResult> resultSelector)
    {
        return outer.GroupJoin(
            inner, 
            outerKeySelector, 
            innerKeySelector,
            (outerElement, innerElements) => resultSelector(outerElement, innerElements.FirstOrDefault()));
    }
}

এটি কেবল নেট নেট লিখেছে এবং এটি প্রত্যাশার মতো কাজ করছে বলে মনে হচ্ছে।

ছোট পরীক্ষা:

        var Ids = new List<int> { 1, 2, 3, 4};
        var items = new List<Tuple<int, string>>
        {
            new Tuple<int, string>(1,"a"),
            new Tuple<int, string>(2,"b"),
            new Tuple<int, string>(4,"d"),
            new Tuple<int, string>(5,"e"),
        };

        var result = Ids.LeftJoin(
            items,
            id => id,
            item => item.Item1,
            (id, item) => item ?? new Tuple<int, string>(id, "not found"));

        result.ToList()
        Count = 4
        [0]: {(1, a)}
        [1]: {(2, b)}
        [2]: {(3, not found)}
        [3]: {(4, d)}

4

পদ্ধতি সিনট্যাক্স ব্যবহার করে এখানে বোঝা মোটামুটি সহজ:

IEnumerable<JoinPair> outerLeft =
    lefts.SelectMany(l => 
        rights.Where(r => l.Key == r.Key)
              .DefaultIfEmpty(new Item())
              .Select(r => new JoinPair { LeftId = l.Id, RightId = r.Id }));

3

এখানে তিনটি সারণী রয়েছে: ব্যক্তি, স্কুল এবং ব্যক্তি_স্কুলগুলি, যা ব্যক্তিরা তাদের পড়াশুনা করা বিদ্যালয়ের সাথে সংযুক্ত করে id তবে আইডি = 6 সহ ব্যক্তিটি ফলাফল লেফ-যোগ গ্রিডে উপস্থাপিত হয়।

List<Person> persons = new List<Person>
{
    new Person { id = 1, name = "Alex", phone = "4235234" },
    new Person { id = 2, name = "Bob", phone = "0014352" },
    new Person { id = 3, name = "Sam", phone = "1345" },
    new Person { id = 4, name = "Den", phone = "3453452" },
    new Person { id = 5, name = "Alen", phone = "0353012" },
    new Person { id = 6, name = "Simon", phone = "0353012" }
};

List<School> schools = new List<School>
{
    new School { id = 1, name = "Saint. John's school"},
    new School { id = 2, name = "Public School 200"},
    new School { id = 3, name = "Public School 203"}
};

List<PersonSchool> persons_schools = new List<PersonSchool>
{
    new PersonSchool{id_person = 1, id_school = 1},
    new PersonSchool{id_person = 2, id_school = 2},
    new PersonSchool{id_person = 3, id_school = 3},
    new PersonSchool{id_person = 4, id_school = 1},
    new PersonSchool{id_person = 5, id_school = 2}
    //a relation to the person with id=6 is absent
};

var query = from person in persons
            join person_school in persons_schools on person.id equals person_school.id_person
            into persons_schools_joined
            from person_school_joined in persons_schools_joined.DefaultIfEmpty()
            from school in schools.Where(var_school => person_school_joined == null ? false : var_school.id == person_school_joined.id_school).DefaultIfEmpty()
            select new { Person = person.name, School = school == null ? String.Empty : school.name };

foreach (var elem in query)
{
    System.Console.WriteLine("{0},{1}", elem.Person, elem.School);
}

যদিও এটি হতে পারে প্রশ্নের উত্তরটি আপনার উত্তর সম্পর্কে কিছু ব্যাখ্যা সরবরাহ করে :)
আমির

2

অভ্যন্তরীণ এবং বাম বাইরের সাথে যোগ দেওয়ার জন্য এটি লিনকিউ সিনট্যাক্সের সাথে তুলনা করে এটি একটি এসকিউএল সিনট্যাক্স। বাম বাইরের যোগদান:

http://www.ozkary.com/2011/07/linq-to-entity-inner-and-left-joins.html

"নিম্নলিখিত উদাহরণটি পণ্য এবং বিভাগের মধ্যে একটি গ্রুপকে যুক্ত করে। এটি মূলত বাম জোড়। catList.DefaultIfEmpty () স্টেটমেন্ট থেকে cl যোগ করে।


1

বাম বাহিরের যোগগুলি লিনক সি তে সম্পাদন করুন // // বাম বাহ্যিক যোগদান করুন

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Child
{
    public string Name { get; set; }
    public Person Owner { get; set; }
}
public class JoinTest
{
    public static void LeftOuterJoinExample()
    {
        Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
        Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
        Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
        Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

        Child barley = new Child { Name = "Barley", Owner = terry };
        Child boots = new Child { Name = "Boots", Owner = terry };
        Child whiskers = new Child { Name = "Whiskers", Owner = charlotte };
        Child bluemoon = new Child { Name = "Blue Moon", Owner = terry };
        Child daisy = new Child { Name = "Daisy", Owner = magnus };

        // Create two lists.
        List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
        List<Child> childs = new List<Child> { barley, boots, whiskers, bluemoon, daisy };

        var query = from person in people
                    join child in childs
                    on person equals child.Owner into gj
                    from subpet in gj.DefaultIfEmpty()
                    select new
                    {
                        person.FirstName,
                        ChildName = subpet!=null? subpet.Name:"No Child"
                    };
                       // PetName = subpet?.Name ?? String.Empty };

        foreach (var v in query)
        {
            Console.WriteLine($"{v.FirstName + ":",-25}{v.ChildName}");
        }
    }

    // This code produces the following output:
    //
    // Magnus:        Daisy
    // Terry:         Barley
    // Terry:         Boots
    // Terry:         Blue Moon
    // Charlotte:     Whiskers
    // Arlene:        No Child

https://dotnetwithhamid.blogspot.in/


1

আমি যুক্ত করতে চাই যে আপনি যদি মোরিলিংক এক্সটেনশানটি পান তবে এখন উভয় সমজাতীয় এবং ভিন্ন ভিন্ন বামদের সাথে যোগ দেয়

http://morelinq.github.io/2.8/ref/api/html/Overload_MoreLinq_MoreEnumerable_LeftJoin.htm

উদাহরণ:

//Pretend a ClientCompany object and an Employee object both have a ClientCompanyID key on them

return DataContext.ClientCompany
    .LeftJoin(DataContext.Employees,                         //Table being joined
        company => company.ClientCompanyID,                  //First key
        employee => employee.ClientCompanyID,                //Second Key
        company => new {company, employee = (Employee)null}, //Result selector when there isn't a match
        (company, employee) => new { company, employee });   //Result selector when there is a match

সম্পাদনা করুন:

পূর্ববর্তী ক্ষেত্রে এটি কাজ করতে পারে তবে মোড়লিংক কোয়েরিকে এসকিউএলে রূপান্তর না করায় এটি আইকুয়ারিকে একটি আইএনমেয়্যারে রূপান্তরিত করে।

পরিবর্তে আপনি এখানে বর্ণিত হিসাবে একটি গ্রুপজয়াইন ব্যবহার করতে পারেন: https://stackoverflow.com/a/24273804/4251433

এটি নিশ্চিত করবে যে এটির পরে আপনার আরও লজিকাল অপারেশন করার প্রয়োজন হলে এটি আইকোয়্যারেবল হিসাবে থাকবে।


1

সহজ উপায় হ'ল লেট কীওয়ার্ড ব্যবহার করা। এটি আমার পক্ষে কাজ করে।

from AItem in Db.A
Let BItem = Db.B.Where(x => x.id == AItem.id ).FirstOrDefault() 
Where SomeCondition
Select new YourViewModel
{
    X1 = AItem.a,
    X2 = AItem.b,
    X3 = BItem.c
}

এটি বাম যোগদানের একটি অনুকরণ। বি টেবিলের প্রতিটি আইটেম যদি কোনও আইটেমের সাথে মেলে না, তবে বিটেমটি শূন্য হয়


0

আপনার যদি কোনও কিছুতে যোগদান এবং ফিল্টার করতে হয় তবে তা যোগ দেওয়ার বাইরেও করা যেতে পারে। সংগ্রহ তৈরির পরে ফিল্টার করা যেতে পারে।

এই ক্ষেত্রে আমি যদি যোগদানের শর্তে এটি করি তবে আমি ফিরে আসা সারিগুলি হ্রাস করব।

টার্নারি অবস্থা ব্যবহৃত হয় (= n == null ? "__" : n.MonDayNote,)

  • যদি বস্তুটি null(কোনও মিল নেই), তবে এর পরে যা আছে তা ফিরিয়ে দিন ?__, এক্ষেত্রে.

  • অন্যথায়, আসতে কি পরে :, n.MonDayNote

অন্যান্য অবদানকারীদের ধন্যবাদ যে আমি এখানেই নিজের ইস্যু দিয়ে শুরু করেছি।


        var schedLocations = (from f in db.RAMS_REVENUE_LOCATIONS
              join n in db.RAMS_LOCATION_PLANNED_MANNING on f.revenueCenterID equals

                  n.revenueCenterID into lm

              from n in lm.DefaultIfEmpty()

              join r in db.RAMS_LOCATION_SCHED_NOTE on f.revenueCenterID equals r.revenueCenterID
              into locnotes

              from r in locnotes.DefaultIfEmpty()
              where f.LocID == nLocID && f.In_Use == true && f.revenueCenterID > 1000

              orderby f.Areano ascending, f.Locname ascending
              select new
              {
                  Facname = f.Locname,
                  f.Areano,
                  f.revenueCenterID,
                  f.Locabbrev,

                  //  MonNote = n == null ? "__" : n.MonDayNote,
                  MonNote = n == null ? "__" : n.MonDayNote,
                  TueNote = n == null ? "__" : n.TueDayNote,
                  WedNote = n == null ? "__" : n.WedDayNote,
                  ThuNote = n == null ? "__" : n.ThuDayNote,

                  FriNote = n == null ? "__" : n.FriDayNote,
                  SatNote = n == null ? "__" : n.SatDayNote,
                  SunNote = n == null ? "__" : n.SunDayNote,
                  MonEmpNbr = n == null ? 0 : n.MonEmpNbr,
                  TueEmpNbr = n == null ? 0 : n.TueEmpNbr,
                  WedEmpNbr = n == null ? 0 : n.WedEmpNbr,
                  ThuEmpNbr = n == null ? 0 : n.ThuEmpNbr,
                  FriEmpNbr = n == null ? 0 : n.FriEmpNbr,
                  SatEmpNbr = n == null ? 0 : n.SatEmpNbr,
                  SunEmpNbr = n == null ? 0 : n.SunEmpNbr,
                  SchedMondayDate = n == null ? dMon : n.MondaySchedDate,
                  LocNotes = r == null ? "Notes: N/A" : r.LocationNote

              }).ToList();
                Func<int, string> LambdaManning = (x) => { return x == 0 ? "" : "Manning:" + x.ToString(); };
        DataTable dt_ScheduleMaster = PsuedoSchedule.Tables["ScheduleMasterWithNotes"];
        var schedLocations2 = schedLocations.Where(x => x.SchedMondayDate == dMon);

0
class Program
{
    List<Employee> listOfEmp = new List<Employee>();
    List<Department> listOfDepart = new List<Department>();

    public Program()
    {
        listOfDepart = new List<Department>(){
            new Department { Id = 1, DeptName = "DEV" },
            new Department { Id = 2, DeptName = "QA" },
            new Department { Id = 3, DeptName = "BUILD" },
            new Department { Id = 4, DeptName = "SIT" }
        };


        listOfEmp = new List<Employee>(){
            new Employee { Empid = 1, Name = "Manikandan",DepartmentId=1 },
            new Employee { Empid = 2, Name = "Manoj" ,DepartmentId=1},
            new Employee { Empid = 3, Name = "Yokesh" ,DepartmentId=0},
            new Employee { Empid = 3, Name = "Purusotham",DepartmentId=0}
        };

    }
    static void Main(string[] args)
    {
        Program ob = new Program();
        ob.LeftJoin();
        Console.ReadLine();
    }

    private void LeftJoin()
    {
        listOfEmp.GroupJoin(listOfDepart.DefaultIfEmpty(), x => x.DepartmentId, y => y.Id, (x, y) => new { EmpId = x.Empid, EmpName = x.Name, Dpt = y.FirstOrDefault() != null ? y.FirstOrDefault().DeptName : null }).ToList().ForEach
            (z =>
            {
                Console.WriteLine("Empid:{0} EmpName:{1} Dept:{2}", z.EmpId, z.EmpName, z.Dpt);
            });
    }
}

class Employee
{
    public int Empid { get; set; }
    public string Name { get; set; }
    public int DepartmentId { get; set; }
}

class Department
{
    public int Id { get; set; }
    public string DeptName { get; set; }
}

আউটপুট


0

আমার অনুরূপ প্রশ্নের উত্তর অনুসারে, এখানে:

লিনক থেকে এসকিউএল বাম বাহিরের লাম্বডা সিনট্যাক্স ব্যবহার করে এবং 2 টি কলামে যুক্ত হওয়া (যৌগিক যোগ কী)

কোডটি এখানে পান , বা আমার গিথুব রেপো ক্লোন করুন এবং খেলুন!

প্রশ্ন:

        var petOwners =
            from person in People
            join pet in Pets
            on new
            {
                person.Id,
                person.Age,
            }
            equals new
            {
                pet.Id,
                Age = pet.Age * 2, // owner is twice age of pet
            }
            into pets
            from pet in pets.DefaultIfEmpty()
            select new PetOwner
            {
                Person = person,
                Pet = pet,
            };

ল্যামডা:

        var petOwners = People.GroupJoin(
            Pets,
            person => new { person.Id, person.Age },
            pet => new { pet.Id, Age = pet.Age * 2 },
            (person, pet) => new
            {
                Person = person,
                Pets = pet,
            }).SelectMany(
            pet => pet.Pets.DefaultIfEmpty(),
            (people, pet) => new
            {
                people.Person,
                Pet = pet,
            });

0

ওভারভিউ: এই কোড স্নিপেটে, আমি দেখিয়েছি যে কীভাবে আইডি অনুসারে গোষ্ঠী করা যায় যেখানে টেবিল 1 এবং টেবিল 2 এর মধ্যে অনেকগুলি সম্পর্ক রয়েছে। আমি আইডি, ফিল্ড 1 এবং ফিল্ড 2 তে গ্রুপ করি। সাবকিউরিটি সহায়ক, যদি কোনও তৃতীয় সারণী অনুসন্ধান প্রয়োজন হয় এবং এটির জন্য বাম সংযুক্তির সম্পর্ক প্রয়োজন হত। আমি একটি বাম যোগদান গ্রুপিং এবং একটি subquery লিনক দেখায়। ফলাফল সমতুল্য।

class MyView
{
public integer Id {get,set};
    public String Field1  {get;set;}
public String Field2 {get;set;}
    public String SubQueryName {get;set;}                           
}

IList<MyView> list = await (from ci in _dbContext.Table1
                                               join cii in _dbContext.Table2
                                                   on ci.Id equals cii.Id

                                               where ci.Field1 == criterion
                                               group new
                                               {
                                                   ci.Id
                                               } by new { ci.Id, cii.Field1, ci.Field2}

                                           into pg
                                               select new MyView
                                               {
                                                   Id = pg.Key.Id,
                                                   Field1 = pg.Key.Field1,
                                                   Field2 = pg.Key.Field2,
                                                   SubQueryName=
                                                   (from chv in _dbContext.Table3 where chv.Id==pg.Key.Id select chv.Field1).FirstOrDefault()
                                               }).ToListAsync<MyView>();


 Compared to using a Left Join and Group new

IList<MyView> list = await (from ci in _dbContext.Table1
                                               join cii in _dbContext.Table2
                                                   on ci.Id equals cii.Id

                       join chv in _dbContext.Table3
                                                  on cii.Id equals chv.Id into lf_chv
                                                from chv in lf_chv.DefaultIfEmpty()

                                               where ci.Field1 == criterion
                                               group new
                                               {
                                                   ci.Id
                                               } by new { ci.Id, cii.Field1, ci.Field2, chv.FieldValue}

                                           into pg
                                               select new MyView
                                               {
                                                   Id = pg.Key.Id,
                                                   Field1 = pg.Key.Field1,
                                                   Field2 = pg.Key.Field2,
                                                   SubQueryName=pg.Key.FieldValue
                                               }).ToListAsync<MyView>();

-1
(from a in db.Assignments
     join b in db.Deliveryboys on a.AssignTo equals b.EmployeeId  

     //from d in eGroup.DefaultIfEmpty()
     join  c in  db.Deliveryboys on a.DeliverTo equals c.EmployeeId into eGroup2
     from e in eGroup2.DefaultIfEmpty()
     where (a.Collected == false)
     select new
     {
         OrderId = a.OrderId,
         DeliveryBoyID = a.AssignTo,
         AssignedBoyName = b.Name,
         Assigndate = a.Assigndate,
         Collected = a.Collected,
         CollectedDate = a.CollectedDate,
         CollectionBagNo = a.CollectionBagNo,
         DeliverTo = e == null ? "Null" : e.Name,
         DeliverDate = a.DeliverDate,
         DeliverBagNo = a.DeliverBagNo,
         Delivered = a.Delivered

     });

-1

বাম বাহ্যিক যোগদানের জন্য সহজ সমাধান :

var setA = context.SetA;
var setB = context.SetB.Select(st=>st.Id).Distinct().ToList();
var leftOuter  = setA.Where(stA=> !setB.Contains(stA.Id)); 

নোট :

  • কর্মক্ষমতা SetB উন্নত করার একটি রূপান্তরিত করা যেতে পারে অভিধান (যে তাহলে সম্পন্ন করা হয় আপনার এটি পরিবর্তন করতে হবে: ! SetB.Contains (stA.Id) ) অথবা একটি HashSet
  • জড়িত যখন একাধিক ক্ষেত্র সেট অপারেশন এবং প্রয়োগ করে এমন একটি শ্রেণি ব্যবহার করে এটি অর্জন করা যেতে পারে : আইকুয়ালিটি কম্পিউটার

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