سؤال

أنا أعمل مع استعلام SQL التالي:

SELECT 
a.AppointmentId,
a.Status,
a.Type,
a.Title,
b.Days,
d.Description,
e.FormId
FROM Appointment a (nolock)
LEFT JOIN AppointmentFormula b (nolock)
ON a.AppointmentId = b.AppointmentId and b.RowStatus = 1
JOIN Type d (nolock)
ON a.Type = d.TypeId
LEFT JOIN AppointmentForm e (nolock)
ON e.AppointmentId = a.AppointmentId
WHERE a.RowStatus = 1
AND a.Type = 1
ORDER BY a.Type

لست متأكدًا من كيفية تحقيق عمليات الانضمام في LINQ.تحتوي جميع جداولي على علاقات مفاتيح خارجية.

هل كانت مفيدة؟

المحلول

وقد تضطر إلى قرص هذا قليلا كما كنت ذاهبا قبالة الكفة، ولكن هناك بضعة أشياء رئيسية أن نأخذ في الاعتبار. إذا كان لديك مجموعة علاقاتك بشكل صحيح في DBML الخاص بك، يجب أن تكون قادرة على القيام ينضم الداخلية ضمنا ومجرد الوصول إلى البيانات من خلال الجدول الأولي الخاص بك. أيضا، ينضم اليسار في LINQ ليست كما مستقيم إلى الأمام ونحن قد نأمل وعليك أن تذهب من خلال بناء الجملة DefaultIfEmpty من أجل تحقيق ذلك. أنا خلقت نوع مجهول هنا، ولكن قد ترغب في وضعه في فئة DTO أو شيء بهذا المعنى. كما أنني لم أعرف ما الذي تريد أن تفعله في حالة بلا قيم، ولكن يمكنك استخدام ؟؟ بناء جملة لتحديد قيمة لإعطاء المتغير إذا كانت القيمة فارغة. اسمحوا لي أن أعرف إذا كان لديك أسئلة إضافية ...

var query = (from a in context.Appointment
join b in context.AppointmentFormula on a.AppointmentId equals b.AppointmentId into temp
from c in temp.DefaultIfEmpty()
join d in context.AppointmentForm on a.AppointmentID equals e.AppointmentID into temp2
from e in temp2.DefaultIfEmpty()
where a.RowStatus == 1 && c.RowStatus == 1 && a.Type == 1
select new {a.AppointmentId, a.Status, a.Type, a.Title, c.Days ?? 0, a.Type.Description, e.FormID ?? 0}).OrderBy(a.Type);

نصائح أخرى

SELECT A.X, B.Y
FROM A JOIN B ON A.X = B.Y

سيؤدي استدعاء أسلوب linq (للانضمام) إلى إنشاء الانضمام أعلاه.

var query = A.Join
(
  B,
  a => a.x,
  b => b.y,
  (a, b) => new {a.x, b.y} //if you want more columns - add them here.
);

SELECT A.X, B.Y
FROM A LEFT JOIN B ON A.X = B.Y

ستنتج استدعاءات أسلوب linq هذه (إلى GroupJoin وSelectMany وDefaultIfEmpty) الانضمام الأيسر أعلاه

var query = A.GroupJoin
(
  B,
  a => a.x,
  b => b.y,
  (a, g) => new {a, g}
).SelectMany
(
  z => z.g.DefaultIfEmpty(),
  (z, b) =>
    new  { x = z.a.x, y = b.y } //if you want more columns - add them here.
);

المفهوم الأساسي هنا هو أن أساليب Linq تنتج نتائج ذات شكل هرمي، وليس أشكال أعمدة وصفوف مسطحة.

  • لينك GroupBy ينتج نتائج على شكل تسلسل هرمي باستخدام مفتاح تجميع مطابق لـ a مجموعة من العناصر (التي قد لا تكون فارغة).SQL GroupBy جملة تنتج مفتاح التجميع مع القيم المجمعة - لا توجد مجموعة فرعية للعمل بها.
  • وبالمثل، لينك GroupJoin ينتج شكلاً هرميًا - سجل أصل مطابق لـ a مجموعة من سجلات الأطفال (والتي قد تكون فارغة).SQL LEFT JOIN يُنتج سجلًا أصلًا مطابقًا لكل سجل فرعي، أو سجلًا فرعيًا فارغًا في حالة عدم وجود تطابقات أخرى.للوصول إلى شكل Sql من شكل Linq، يجب على المرء فك مجموعة السجلات الفرعية باستخدامه SelectMany - والتعامل مع المجموعات الفارغة من سجلات الأطفال باستخدام DefaultIfEmpty.

وهذه محاولتي لتوضيح SQL في السؤال:

var query =
  from a in Appointment
  where a.RowStatus == 1
  where a.Type == 1
  from b in a.AppointmentFormula.Where(af => af.RowStatus == 1).DefaultIfEmpty()
  from d in a.TypeRecord //a has a type column and is related to a table named type, disambiguate the names
  from e in a.AppointmentForm.DefaultIfEmpty()
  order by a.Type
  select new { a.AppointmentId, a.Status, a.Type, a.Title, b.Days, d.Description, e.Form }

إذا كنت تريد الحفاظ على (NOLOCK) تلميحات، ولدي <لأ href = "http://ryancoder.blogspot.com/2010/06/execute-linq-queries-without-locking.html" يختلط = " نوفولو noreferrer "> المدون حل مفيد استخدام طرق الإرشاد في C #. لاحظ أن هذا هو نفس مضيفا تلميحات NOLOCK إلى كل جدول في الاستعلام.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top