লিনক্ ল্যাম্বডায় একাধিক টেবিলের মধ্যে কীভাবে যোগদান সম্পাদন করবেন


91

আমি লিনকিউতে একাধিক টেবিলের মধ্যে একটি জয়েন করার চেষ্টা করছি । আমার নিচের ক্লাসগুলি রয়েছে:

Product {Id, ProdName, ProdQty}

Category {Id, CatName}

ProductCategory{ProdId, CatId} //association table

এবং আমি নিম্নলিখিত কোড ব্যবহার (যেখানে product, categoryএবং productcategoryউপরে শ্রেনীর উদাহরণ স্বরূপ):

var query = product.Join(productcategory, p => p.Id, pc => pc.ProdID, (p, pc) => new {product = p, productcategory = pc})
                   .Join(category, ppc => ppc.productcategory.CatId, c => c.Id, (ppc, c) => new { productproductcategory = ppc, category = c});

এই কোডের সাহায্যে আমি নিম্নলিখিত ক্লাসের একটি বস্তু পেয়েছি:

QueryClass { productproductcategory, category}

যেখানে প্রোডাক্ট প্রোডাক্ট্যাক্টরিও টাইপ করা হয়:

ProductProductCategoryClass {product, productcategory}

যোগদান করা "টেবিল" কোথায় আছে তা আমি বুঝতে পারছি না, আমি এমন একক শ্রেণীর প্রত্যাশা করছিলাম যাতে এতে জড়িত শ্রেণীর সমস্ত বৈশিষ্ট্য থাকে।

আমার লক্ষ্যটি কোয়েরির ফলে কিছু বৈশিষ্ট্য সহ অন্য একটি অবজেক্টকে পপুলেট করা to

CategorizedProducts catProducts = query.Select(m => new { m.ProdId = ???, m.CatId = ???, //other assignments });

আমি কীভাবে এই লক্ষ্য অর্জন করতে পারি?


আমি বুঝতে পারিনি ... কেন এম.প্রডআইডি = ??? প্রোডআইডি = মিটারের পরিবর্তে ?
অ্যাড্রিয়ানো পুনরায়

কারণ আমি কীভাবে নেভিগেট করব এবং প্রোডআইডি করব তা আগে থেকে জানি না
সিক্সিও মিয়ামি

উত্তর:


181

যোগদানের জন্য, আমি সুস্পষ্টভাবে গোপন করা সমস্ত বিবরণের জন্য কোয়েরি-সিনট্যাক্সকে দৃ strongly়ভাবে পছন্দ করি (এর মধ্যে সবচেয়ে কম নয় যে বিন্দু-সিনট্যাক্সের সমতুল্য যে পথে মধ্যবর্তী প্রজেকশনগুলির সাথে জড়িত স্বচ্ছ শনাক্তকারী)। যাইহোক, আপনি ল্যাম্বডাস সম্পর্কে জিজ্ঞাসা করেছিলেন যা আমি মনে করি আপনার যা দরকার তা আছে - আপনার কেবল এটি একসাথে রাখা দরকার।

var categorizedProducts = product
    .Join(productcategory, p => p.Id, pc => pc.ProdId, (p, pc) => new { p, pc })
    .Join(category, ppc => ppc.pc.CatId, c => c.Id, (ppc, c) => new { ppc, c })
    .Select(m => new { 
        ProdId = m.ppc.p.Id, // or m.ppc.pc.ProdId
        CatId = m.c.CatId
        // other assignments
    });

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

এছাড়াও, আপনি Selectদ্বিতীয়টির শেষ ল্যাম্বডায় ফেলে দিতে পারেন Join(আবার শর্তাদির ফলাফলের উপর নির্ভর করে এমন কোনও অপারেশন নেই) যা দেবে:

var categorizedProducts = product
    .Join(productcategory, p => p.Id, pc => pc.ProdId, (p, pc) => new { p, pc })
    .Join(category, ppc => ppc.pc.CatId, c => c.Id, (ppc, c) => new {
        ProdId = ppc.p.Id, // or ppc.pc.ProdId
        CatId = c.CatId
        // other assignments
    });

... এবং ক্যোয়ারী সিনট্যাক্সে আপনাকে বিক্রি করার শেষ প্রচেষ্টা করা, এটি দেখতে এরকম হবে:

var categorizedProducts =
    from p in product
    join pc in productcategory on p.Id equals pc.ProdId
    join c in category on pc.CatId equals c.Id
    select new {
        ProdId = p.Id, // or pc.ProdId
        CatId = c.CatId
        // other assignments
    };

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


4
ধন্যবাদ আপনার সমাধানটি আরও সম্পূর্ণ। আমি সম্মত হই যে কিছু ক্ষেত্রে কোয়েরি সিনট্যাক্স আরও স্পষ্ট তবে আপনি সঠিক অনুমান করেছেন, আমাকে ল্যাম্বডা ব্যবহার করতে বলা হয়েছে। তবুও আমাকে এটি 6 টি টেবিলের সাথে যুক্ত হতে হবে, এবং এই ক্ষেত্রে ডট সংকেতটি আরও ঝরঝরে
সিক্সিও মিয়ামি

@ দেদেজিজার যদি JOINবিবৃতিতে আমাদের অতিরিক্ত শর্ত প্রয়োজন ? আমরা যে কিভাবে করব? উদাহরণস্বরূপ, join pc in productcategory on p.Id equals pc.ProdIdলাইনে, আমাদের যুক্ত করা দরকার and p.Id == 1
হারাম্বে অ্যাটাক হেলিকপ্টার

এটি সন্দেহজনক বলে মনে হয় যে আপনি p.Id == 1যেহেতু ফিল্টার এটির চেয়ে অনেক বেশি চান কারণ এটি যুক্ত হওয়ার মাপকাঠি। আপনি করতে চাই একটি একাধিক মানদণ্ডের উপর যোগদানের সাধারণত একটি বেনামী টাইপ ব্যবহার করা: join pc in productcategory on new { Id = p.Id, Other = p.Other } equals new { Id = pc.ProdId, Other = pc.Other }। এটি লিনক-টু-অবজেক্টে কাজ করে এবং আমি অনুমান করি যে এটি একইভাবে ডাটাবেস অনুসন্ধানগুলির সাথেও কাজ করবে। ডেটাবেসগুলির সাহায্যে আপনি বিদেশী কীগুলি যথাযথ হিসাবে সংজ্ঞায়িত করে এবং সম্পর্কিত সম্পত্তির মাধ্যমে সম্পর্কিত ডেটা অ্যাক্সেস করে জটিল যোগদানের প্রশ্নাগুলি আটকাতে সক্ষম হতে পারেন।
ডেগিজার

পরিষ্কার সমাধানের জন্য আপনাকে ধন্যবাদ।
টমাস.বেঞ্জ

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

12

আপনি যা দেখেছেন তা হ'ল - এবং এটিই যা আপনি চেয়েছিলেন, এখানে:

(ppc, c) => new { productproductcategory = ppc, category = c}

এটি একটি ল্যাম্বডা এক্সপ্রেশন those দুটি বৈশিষ্ট্যের সাথে একটি বেনামি টাইপ প্রত্যাবর্তন করবে।

আপনার শ্রেণিবদ্ধ পণ্যগুলিতে আপনাকে কেবল সেই বৈশিষ্ট্যগুলির মধ্য দিয়ে যেতে হবে:

CategorizedProducts catProducts = query.Select(
      m => new { 
             ProdId = m.productproductcategory.product.Id, 
             CatId = m.category.CatId, 
             // other assignments 
           });

ধন্যবাদ আমি বেনামে বর্গ সম্পর্কে আলোচনাটি বুঝতে পারি তবে এর বৈশিষ্ট্যগুলিতে কোয়েরিটি পূরণ করে এমন কেবল শ্রেণীর অবজেক্ট রয়েছে? এবং আমি 2 যোগদানের পরে কী হবে? প্রোডাক্ট প্রোডাক্ট ক্যাটাগরি.প্রোডাক্ট ক্যাটাগরির সাথে যোগ হয় না?
CiccioMiami

@ সিসিও মিয়ামি: ঠিক আছে, সম্পত্তিগুলি হ'ল বস্তুর উল্লেখ । আপনি "যোগদান না করা" বলতে আপনি কী বোঝাতে চেয়েছেন তা সত্য নয় - আপনি যে প্রশ্নটি পেতে চান তা থেকে আপনি কী তথ্য পান না?
জন স্কিটি 13

প্রথম যোগদানের সাথে আমি পণ্য এবং পণ্যশ্রেণীর মধ্যে যোগ পেতে পারি। দ্বিতীয়টির সাথে আমি প্রোডাক্ট ক্যাটাগরি (যোগ হওয়া পণ্য) এবং বিভাগের মধ্যে যোগ পেতে পারি। তার মানে একাধিক যোগদানের তথ্য কেবলমাত্র প্রোডাক্ট প্রোডাক্টেক্স বিভাগে অন্তর্ভুক্ত। এর অর্থ হ'ল পণ্য (এবং বিভাগ) সবেমাত্র পণ্যশ্রেণীতে যুক্ত হয়েছে।
CiccioMiami

4
@ সিসিও মিয়ামি: দুঃখিত, আমি আপনাকে অনুসরণ করছি না - তবে আপনি যদি যোগদানটি নির্দিষ্ট করেন তবে এটি তা করবে। আপনি আমার উত্তরে কোডটি ব্যবহার করার চেষ্টা করেছেন? এটি কি আপনি চান না না?
জন স্কিটি

দুঃখিত, আমি আপনার কোড পেতে চাই। CatId কাজ অ্যাসাইনমেন্ট । জন্য ProdIdএটা করা উচিত m.productproductcategory.product.Idবা m.productproductcategory.productcategory.ProdId। দুই বরাদ্দকরণ ভিন্ন, প্রথম পণ্য (সাথে যোগ হয় productcategory) দ্বিতীয় সাথে আছেন productcategoryউভয় সঙ্গে যোগ দেন productএবং category। আপনি কি আমার যুক্তি অনুসরণ করেন?
CiccioMiami

5

আমার প্রকল্প থেকে এই নমুনা কোডটি দেখুন

public static IList<Letter> GetDepartmentLettersLinq(int departmentId)
{
    IEnumerable<Letter> allDepartmentLetters =
        from allLetter in LetterService.GetAllLetters()
        join allUser in UserService.GetAllUsers() on allLetter.EmployeeID equals allUser.ID into usersGroup
        from user in usersGroup.DefaultIfEmpty()// here is the tricky part
        join allDepartment in DepartmentService.GetAllDepartments() on user.DepartmentID equals allDepartment.ID
        where allDepartment.ID == departmentId
        select allLetter;

    return allDepartmentLetters.ToArray();
}

এই কোডটিতে আমি 3 টি টেবিলগুলিতে যোগ দিয়েছি এবং আমি কোথাও ক্লজ থেকে যোগ দেওয়ার শর্তটি বন্ধ করে দিয়েছি

দ্রষ্টব্য: পরিষেবাদি ক্লাসগুলি কেবল ডেটাবেস ক্রিয়াকলাপকে আবদ্ধ (এনক্যাপসুলেট) করে


2
 public ActionResult Index()
    {
        List<CustomerOrder_Result> obj = new List<CustomerOrder_Result>();

       var  orderlist = (from a in db.OrderMasters
                         join b in db.Customers on a.CustomerId equals b.Id
                         join c in db.CustomerAddresses on b.Id equals c.CustomerId
                         where a.Status == "Pending"
                         select new
                         {
                             Customername = b.Customername,
                             Phone = b.Phone,
                             OrderId = a.OrderId,
                             OrderDate = a.OrderDate,
                             NoOfItems = a.NoOfItems,
                             Order_amt = a.Order_amt,
                             dis_amt = a.Dis_amt,
                             net_amt = a.Net_amt,
                             status=a.Status,  
                             address = c.address,
                             City = c.City,
                             State = c.State,
                             Pin = c.Pin

                         }) ;
       foreach (var item in orderlist)
       {

           CustomerOrder_Result clr = new CustomerOrder_Result();
           clr.Customername=item.Customername;
           clr.Phone = item.Phone;
           clr.OrderId = item.OrderId;
           clr.OrderDate = item.OrderDate;
           clr.NoOfItems = item.NoOfItems;
           clr.Order_amt = item.Order_amt;
           clr.net_amt = item.net_amt;
           clr.address = item.address;
           clr.City = item.City;
           clr.State = item.State;
           clr.Pin = item.Pin;
           clr.status = item.status;

           obj.Add(clr);



       }

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

0
var query = from a in d.tbl_Usuarios
                    from b in d.tblComidaPreferidas
                    from c in d.tblLugarNacimientoes
                    select new
                    {
                        _nombre = a.Nombre,
                        _comida = b.ComidaPreferida,
                        _lNacimiento = c.Ciudad
                    };
        foreach (var i in query)
        {
            Console.WriteLine($"{i._nombre } le gusta {i._comida} y nació en {i._lNacimiento}");
        }

কেবল এটি সহজ, তবে ল্যাম্বডা এক্সপ্রেসের সাথে আরও ভাল কিছু লোকেরা বলেছেন।
অ্যালেক্স মার্টিনেজ

0

এটি একটি সময় হয়েছে কিন্তু আমার উত্তর কারও সাহায্য করতে পারে:

আপনি যদি ইতিমধ্যে সম্পর্কটিকে সঠিকভাবে সংজ্ঞা দিয়ে থাকেন তবে আপনি এটি ব্যবহার করতে পারেন:

        var res = query.Products.Select(m => new
        {
            productID = product.Id,
            categoryID = m.ProductCategory.Select(s => s.Category.ID).ToList(),
        }).ToList();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.