لينك إلى Sql:صلات خارجية متعددة على اليسار
-
06-07-2019 - |
سؤال
أواجه بعض المشاكل في معرفة كيفية استخدام أكثر من صلة خارجية يسرى باستخدام LINQ إلى SQL.أفهم كيفية استخدام صلة خارجية يسرى واحدة.أنا أستخدم VB.NET.يوجد أدناه بناء جملة SQL الخاص بي.
تي إس كيو إل
SELECT
o.OrderNumber,
v.VendorName,
s.StatusName
FROM
Orders o
LEFT OUTER JOIN Vendors v ON
v.Id = o.VendorId
LEFT OUTER JOIN Status s ON
s.Id = o.StatusId
WHERE
o.OrderNumber >= 100000 AND
o.OrderNumber <= 200000
المحلول
قد يكون هذا أنظف (لا تحتاج إلى كل into
صياغات):
var query =
from order in dc.Orders
from vendor
in dc.Vendors
.Where(v => v.Id == order.VendorId)
.DefaultIfEmpty()
from status
in dc.Status
.Where(s => s.Id == order.StatusId)
.DefaultIfEmpty()
select new { Order = order, Vendor = vendor, Status = status }
//Vendor and Status properties will be null if the left join is null
هنا مثال آخر للانضمام إلى اليسار
var results =
from expense in expenseDataContext.ExpenseDtos
where expense.Id == expenseId //some expense id that was passed in
from category
// left join on categories table if exists
in expenseDataContext.CategoryDtos
.Where(c => c.Id == expense.CategoryId)
.DefaultIfEmpty()
// left join on expense type table if exists
from expenseType
in expenseDataContext.ExpenseTypeDtos
.Where(e => e.Id == expense.ExpenseTypeId)
.DefaultIfEmpty()
// left join on currency table if exists
from currency
in expenseDataContext.CurrencyDtos
.Where(c => c.CurrencyID == expense.FKCurrencyID)
.DefaultIfEmpty()
select new
{
Expense = expense,
// category will be null if join doesn't exist
Category = category,
// expensetype will be null if join doesn't exist
ExpenseType = expenseType,
// currency will be null if join doesn't exist
Currency = currency
}
نصائح أخرى
لا أستطيع الوصول إلى VisualStudio (أنا على جهاز Mac الخاص بي)، ولكن باستخدام المعلومات من http://bhaidar.net/cs/archive/2007/08/01/left-outer-join-in-linq-to-sql.aspx يبدو أنك قد تكون قادرًا على القيام بشيء مثل هذا:
var query = from o in dc.Orders
join v in dc.Vendors on o.VendorId equals v.Id into ov
from x in ov.DefaultIfEmpty()
join s in dc.Status on o.StatusId equals s.Id into os
from y in os.DefaultIfEmpty()
select new { o.OrderNumber, x.VendorName, y.StatusName }
لقد اكتشفت كيفية استخدام العديد من الصلات الخارجية اليسرى في VB.NET باستخدام LINQ إلى SQL:
Dim db As New ContractDataContext()
Dim query = From o In db.Orders _
Group Join v In db.Vendors _
On v.VendorNumber Equals o.VendorNumber _
Into ov = Group _
From x In ov.DefaultIfEmpty() _
Group Join s In db.Status _
On s.Id Equals o.StatusId Into os = Group _
From y In os.DefaultIfEmpty() _
Where o.OrderNumber >= 100000 And o.OrderNumber <= 200000 _
Select Vendor_Name = x.Name, _
Order_Number = o.OrderNumber, _
Status_Name = y.StatusName
في VB.NET باستخدام الوظيفة،
Dim query = From order In dc.Orders
From vendor In
dc.Vendors.Where(Function(v) v.Id = order.VendorId).DefaultIfEmpty()
From status In
dc.Status.Where(Function(s) s.Id = order.StatusId).DefaultIfEmpty()
Select Order = order, Vendor = vendor, Status = status
أعتقد أنه يجب أن تكون قادرًا على اتباع الطريقة المستخدمة في هذا بريد.يبدو الأمر قبيحًا حقًا، لكنني أعتقد أنه يمكنك القيام بذلك مرتين والحصول على النتيجة التي تريدها.
أتساءل عما إذا كانت هذه هي الحالة التي من الأفضل أن تستخدمها DataContext.ExecuteCommand(...)
بدلاً من التحويل إلى linq.
أنا أستخدم استعلام linq هذا لطلبي.إذا كان هذا يتوافق مع متطلباتك، يمكنك الرجوع إلى هذا.لقد انضممت هنا (صلة خارجية يسرى) مع 3 جداول.
Dim result = (From csL In contractEntity.CSLogin.Where(Function(cs) cs.Login = login AndAlso cs.Password = password).DefaultIfEmpty
From usrT In contractEntity.UserType.Where(Function(uTyp) uTyp.UserTypeID = csL.UserTyp).DefaultIfEmpty ' <== makes join left join
From kunD In contractEntity.EmployeeMaster.Where(Function(kunDat) kunDat.CSLoginID = csL.CSLoginID).DefaultIfEmpty
Select New With {
.CSLoginID = csL.CSLoginID,
.UserType = csL.UserTyp}).ToList()