লিনকিউ এবং ল্যাম্বডায় যেখানে / যোগ দিন


457

লিনকিউ এবং ল্যাম্বডায় লেখা একটি প্রশ্নের সাথে আমার সমস্যা হচ্ছে। এখনও অবধি, আমি এখানে আমার কোডটি অনেক ত্রুটি পাচ্ছি:

int id = 1;
var query = database.Posts.Join(database.Post_Metas,
                                post => database.Posts.Where(x => x.ID == id),
                                meta => database.Post_Metas.Where(x => x.Post_ID == id),
                                (post, meta) => new { Post = post, Meta = meta });

আমি লিনকিউ ব্যবহারে নতুন, তাই আমি নিশ্চিত না যে এই ক্যোয়ারীটি সঠিক কিনা।


11
তুমি অর্জন করার জন্য কি চেষ্টা করতেছ?
জার্মানি রদ্রিগেজ

4
আপনি একটি বাক্যটিতে ক্যোয়ারীটি কী করতে চান?
শিকারি

6
আপনার কী নির্বাচকরা হয় পথ খুব জটিল। আপনি যদি আইডির মাধ্যমে নির্বাচন করতে চান তবে x => x.ID ঠিক আছে।
এরিক লিপার্ট

1
আমি সেই পোস্টের জন্য ডাটাবেস এবং মেটা ডেটা থেকে একটি পোস্ট পেতে চেয়েছিলাম।
ডেভিড

উত্তর:


1053

আমি দেখতে পেয়েছি যে আপনি যদি এসকিউএল সিনট্যাক্সের সাথে পরিচিত হন, লিনকুই ক্যোয়ারী বাক্য গঠনটি ব্যবহার করা আরও পরিষ্কার, আরও প্রাকৃতিক এবং ত্রুটিগুলি চিহ্নিত করা সহজ করে তোলে:

var id = 1;
var query =
   from post in database.Posts
   join meta in database.Post_Metas on post.ID equals meta.Post_ID
   where post.ID == id
   select new { Post = post, Meta = meta };

আপনি যদি সত্যিই ল্যাম্বডাস ব্যবহারে আটকে থাকেন তবে আপনার বাক্য গঠনটি বেশ খানিকটা বন্ধ। লিনকিউ এক্সটেনশন পদ্ধতিগুলি ব্যবহার করে এখানে একই প্রশ্নটি রয়েছে:

var id = 1;
var query = database.Posts    // your starting point - table in the "from" statement
   .Join(database.Post_Metas, // the source table of the inner join
      post => post.ID,        // Select the primary key (the first part of the "on" clause in an sql "join" statement)
      meta => meta.Post_ID,   // Select the foreign key (the second part of the "on" clause)
      (post, meta) => new { Post = post, Meta = meta }) // selection
   .Where(postAndMeta => postAndMeta.Post.ID == id);    // where statement

10
@ এমানুয়েল গ্রিকো, আপনার সম্পাদনা সম্পর্কিত, "আইডি ক্ষেত্রগুলিতে সাম্যতা যোগ শর্তে সেট করা আছে; আপনার যেখানে বিধিটি ব্যবহার করার দরকার নেই!": যেখানে শর্তটি আইডি ক্ষেত্রের মধ্যে সাম্যতার পরীক্ষা করছে না, এটি পোস্ট আইডির মধ্যে সাম্যতার পরীক্ষা করছে কলামের বাইরে কলাম এবং আইডি প্যারামিটার ঘোষণা করা হয়েছে।
ড্যানিয়েল শেফার 15

9
এর অসাধারণ টুকরোটি lambdaহ'ল উদ্ধৃতিটি ব্যবহার করা এবং বোঝার পক্ষে সহজ
পাইওটর কুলা

1
দুর্দান্ত উদাহরণ
খেলনা 21

1
কখনও কখনও ল্যাম্বডায় ব্যাখ্যা ল্যাম্বডায় লেখা হয়। ভাল করে বুঝিয়েছি।
চিমটি

80

আপনি এই দুটি উপায় যেতে পারে। ব্যবহার LINQPad এবং একটি ডামি ডাটাবেস, আমি নিম্নলিখিত প্রশ্নের নির্মিত (যদি তুমি LINQ নতুন অমূল্য):

Posts.Join(
    Post_metas,
    post => post.Post_id,
    meta => meta.Post_id,
    (post, meta) => new { Post = post, Meta = meta }
)

অথবা

from p in Posts
join pm in Post_metas on p.Post_id equals pm.Post_id
select new { Post = p, Meta = pm }

এই বিশেষ ক্ষেত্রে, আমি লিনকিউ সিনট্যাক্সটি পরিষ্কার বলে মনে করি (আমি পড়তে সবচেয়ে সহজ) এর উপর নির্ভর করে দুজনের মধ্যে পরিবর্তন করি)।

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

var post = Posts.Single(p => p.ID == 1);
var metas = post.Post_metas.ToList();

আপনি যদি এন +1 সমস্যা এড়াতে চান, তবে আপনি স্পষ্টভাবে লিনকিউকে এসকিউএলকে সমস্ত প্রকারের আইটেম একসাথে লোড করতে বলতে পারেন (যদিও আপনি এল 2 এস এর সাথে বেশি পরিচিত হওয়ার জন্য এটি একটি উন্নত বিষয় হতে পারে)। নীচের উদাহরণটিতে বলা আছে "আপনি যখন কোনও পোস্ট লোড করেন, তার সাথে সম্পর্কিত সমস্ত রেকর্ড 'পোস্ট_মেটাস' সম্পত্তি দ্বারা উপস্থাপিত বিদেশী কী এর মাধ্যমেও লোড করুন:

var dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Post>(p => p.Post_metas);

var dataContext = new MyDataContext();
dataContext.LoadOptions = dataLoadOptions;

var post = Posts.Single(p => p.ID == 1); // Post_metas loaded automagically

একই ধরণের, বা বিভিন্ন ধরণের জন্য LoadWithএকক সেটটিতে অনেকগুলি কল করা সম্ভব DataLoadOptions। আপনি যদি এই প্রচুর পরিমাণে করেন তবে আপনি কেবল ক্যাচিং বিবেচনা করতে পারেন।


1
লিনকপ্যাড এবং সিআরএম 2016 ?
কিকিনেট

49

ড্যানিয়েলের সিনট্যাক্স সম্পর্কের একটি ভাল ব্যাখ্যা রয়েছে, তবে তাদের বুঝতে এটি আরও সহজ করার জন্য আমি এই দলিলটি আমার দলের জন্য এক সাথে রেখেছি। আশা করি এটি কাউকে সাহায্য করবেএখানে চিত্র বর্ণনা লিখুন


আপনি যখন আমরা এখানে আছি ঠিক তেমন মানগুলির তালিকার সাথে কাজ করছেন তখন এটি কার্যকর হবে না। বস্তুটিতে কোনও আইডি সম্পত্তি নেই।
টালস্পফ 27

আমি এটি সত্যিই দরকারী খুঁজে পেয়েছি, কিন্তু আমি একটি ত্রুটি পেয়েছি যার জন্য আমাকে যোগদানের কলাম যুক্ত করতে হবে। @ মার্ক বাইয়ার্স পোস্ট করা উত্তরটিও দেখে, যোগদানকারী কলামটির Post_IDদ্বিতীয় উফের ক্ষেত্র রয়েছে meta => meta.Post_ID। এই দৃষ্টান্তের উদাহরণে, g.idমূল নির্বাচনী বিবৃতিটির অংশটি JOIN gStatus g on g.idচূড়ান্ত লাম্বডা অভিব্যক্তিতে প্রতিলিপি করা হয় না।
সসেজফিনজার্স

3
আমি ওপি দ্বারা পোস্ট করা প্রকৃত লিনকটির জবাব দেওয়ার জন্য একটি রেফারেন্স হিসাবে এটি পোস্ট করার চেষ্টা করছিলাম না, এসকিউএলকে একটি লিনাক ফর্ম্যাটে কীভাবে স্থানান্তরিত করা যায় তার জন্য এটি আরও একটি রেফারেন্স ছিল যাতে আমার ইনপুটগুলি মূল প্রশ্নের চেয়ে কিছুটা আলাদা ছিল। আমি যদি জিস্ট্যাটাস মানগুলির জন্য একটি শ্রেণি তৈরি করে থাকি তবে আমি এটিতে একটি আইডি সম্পত্তি রেখে দিতাম এবং হ্যাঁ এটি g => g.id এর সাথে যোগ দিতাম কোডটি যতটা সম্ভব সহজ রাখার চেষ্টা করার জন্য আমি মানগুলির একটি তালিকা ব্যবহার করেছি।
টালস্পফ 27

@ ট্যালসফৌ 27 তাই এসকিউএল কোয়েরিতে কেন এটি জি.আইডি-তে জিস্ট্যাটাসে যোগ দেয়? এটা কি ভুল নাকি ইচ্ছাকৃত?
ড্রামি

@ স্ক্র্যামি টেবিলের মধ্যে ড্রামির প্রতিটি কলামের একটি নাম থাকতে হবে, সুতরাং যেহেতু এই আইডিগুলি ধরে রাখার জন্য এটি কঠোরভাবে 1 টি কলামের টেবিল ছিল, তাই আমি কেবল আইডি নামের একটি কলাম ব্যবহার করেছি, তালিকার <int> এর কোনও সমস্যা নেই। যদি আমি এটির মতো সেট আপ public class IdHolder{ int id } করে রেখেছিলাম List<IdHolder> gStatus = new List<IdHolder>(); gStatus.add(new IdHolder(){id = 7}); gStatus.add(new IdHolder(){id = 8}); তবে সেই বস্তুটি জিস্ট্যাটাসে ব্যবহার করা হয়েছে তবে এটি লিনককে পরিবর্তিত করে এটির কোনও পরিবর্তন ঘটবে কি t =>t.value.TaskStatusId, g=>g.id ?
টালস্পফ 27

37

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

var query = database.Posts.Join(database.Post_Metas,
                                post => post.ID,
                                meta => meta.Post_ID,
                                (post, meta) => new { Post = post, Meta = meta });

আপনি মূল স্লেকের অংশ হিসাবে নয়, পরে ক্লজটি প্রয়োগ করতে পারেন।


9

পোস্ট করা হচ্ছে কারণ যখন আমি লিনকিউ + সত্তা ফ্রেমওয়ার্ক শুরু করেছি তখন আমি এই উদাহরণগুলিকে একদিনের জন্য তাকাতে থাকি।

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

database
  .Posts
  .Where(post => post.ID == id)
  .Select(post => new { post, post.Meta });

আপনি যদি প্রথমে কোডটি করে থাকেন তবে আপনি সম্পত্তিটি এভাবে সেট আপ করতে চান:

class Post {
  [Key]
  public int ID {get; set}
  public int MetaID { get; set; }
  public virtual Meta Meta {get; set;}
}

5

আমি এরকম কিছু করেছি;

var certificationClass = _db.INDIVIDUALLICENSEs
    .Join(_db.INDLICENSECLAsses,
        IL => IL.LICENSE_CLASS,
        ILC => ILC.NAME,
        (IL, ILC) => new { INDIVIDUALLICENSE = IL, INDLICENSECLAsse = ILC })
    .Where(o => 
        o.INDIVIDUALLICENSE.GLOBALENTITYID == "ABC" &&
        o.INDIVIDUALLICENSE.LICENSE_TYPE == "ABC")
    .Select(t => new
        {
            value = t.PSP_INDLICENSECLAsse.ID,
            name = t.PSP_INDIVIDUALLICENSE.LICENSE_CLASS,                
        })
    .OrderBy(x => x.name);

4

এটি কিছু হতে পারে

var myvar = from a in context.MyEntity
            join b in context.MyEntity2 on a.key equals b.key
            select new { prop1 = a.prop1, prop2= b.prop1};

1

1 সমান 1 দুটি পৃথক টেবিল যোগ

var query = from post in database.Posts
            join meta in database.Post_Metas on 1 equals 1
            where post.ID == id
            select new { Post = post, Meta = meta };

1

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

var query = database.Posts.Join(database.Post_Metas,
                                post => post.postId, // Primary Key
                                meta => meat.postId, // Foreign Key
                                (post, meta) => new { Post = post, Meta = meta });

সমতুল্য এসকিউএল ক্যোয়ারী

Select * FROM Posts P
INNER JOIN Post_Metas pm ON pm.postId=p.postId

তৃতীয়
পরমের

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