كيف يمكنني الأكثر أناقة التعبير عن اليسار الانضمام الكلي SQL كما ينق الاستعلام
سؤال
SQL:
SELECT
u.id,
u.name,
isnull(MAX(h.dateCol), '1900-01-01') dateColWithDefault
FROM universe u
LEFT JOIN history h
ON u.id=h.id
AND h.dateCol<GETDATE()-1
GROUP BY u.Id, u.name
المحلول
الحل وإن كان يؤجل التعامل مع قيمة فارغة إلى رمز يمكن أن يكون:
التاريخ والوقت أمس = DateTime.الآن.تاريخ.AddDays(-1);
var collection=
from u in db.Universe
select new
{
u.id,
u.name,
MaxDate =(DateTime?)
(
from h in db.History
where u.Id == h.Id
&& h.dateCol < yesterday
select h.dateCol
).Max()
};
هذا لا تنتج بالضبط نفس SQL, ولكن لا توفر نفس النتيجة المنطقية.ترجمة "معقدة" SQL استعلامات LINQ ليست دائما واضحة.
نصائح أخرى
var collection=
from u in db.Universe
select new
{
u.id,
u.name,
MaxDate =(DateTime?)
(
from h in db.History
where u.Id == h.Id
&& h.dateCol < yesterday
select h.dateCol
).Max()
};
فقط أنت رمز أعلاه و هذا يجب أن تعمل بشكل جيد!
هذه ليست إجابة كاملة بالنسبة لك, ولكن على اليسار الانضمام إلى قطعة يمكنك استخدام DefaultIfEmpty المشغل مثل ذلك:
var collection =
from u in db.Universe
join history in db.History on u.id = history.id into temp
from h in temp.DefaultIfEmpty()
where h.dateCol < DateTime.Now.Date.AddDays(-1)
select u.id, u.name, h.dateCol ?? '1900-01-01'
لم يكن بحاجة إلى أن تفعل أي groupby الأوامر بعد ، لذا تركت هذا لا ترسل لك الطريق الخطأ.اثنين آخرين سريعة الأشياء ملاحظة.لقد كنت غير قادر على الانضمام في الواقع على معلمتين على الرغم من أن كما سبق هناك طرق للالتفاف على ذلك.أيضا،??المشغل يعمل بشكل جيد حقا في مكان isnull في SQL.
كنت تريد الذهاب إلى استخدام join into
بناء على إنشاء مجموعة الاستعلام.
TestContext db = new TestContext(CreateSparqlTripleStore());
var q = from a in db.Album
join t in db.Track on a.Name equals t.AlbumName into tracks
select new Album{Name = a.Name, Tracks = tracks};
foreach(var album in q){
Console.WriteLine(album.Name);
foreach (Track track in album.Tracks)
{
Console.WriteLine(track.Title);
}
}