我正在使用以下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中实现JOIN。我的所有表都有外键关系。
答案 0 :(得分:29)
SELECT A.X, B.Y
FROM A JOIN B ON A.X = B.Y
这个linq方法调用(加入)将生成上面的Join。
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)将产生上面的Left Join
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
生成的结果形式为层次结构,其分组键与集合元素(可能不为空)匹配。 SQL的GroupBy
子句生成具有聚合值的分组键 - 没有可用的子集合。GroupJoin
生成一个分层形状 - 与父记录的集合匹配的父记录(可能为空)。 Sql的LEFT JOIN
生成与每个子记录匹配的父记录,如果没有其他匹配则生成空子记录。要从Linq的形状获得Sql的形状,必须使用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 }
答案 1 :(得分:5)
当我离开袖口时,你可能需要略微调整一下,但有几个要记住的重要事项。如果在dbml中正确设置了关系,则应该可以隐式执行内部联接,只需通过初始表访问数据。此外,LINQ中的左连接并不像我们希望的那样直截了当,您必须通过DefaultIfEmpty语法才能实现它。我在这里创建了一个匿名类型,但您可能想要放入DTO类或其他类似的东西。在nulls的情况下我也不知道你想做什么,但你可以使用??语法定义一个值,如果值为null,则给出变量。如果您还有其他问题,请与我们联系......
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);
答案 2 :(得分:1)
如果你想保留(NOLOCK)提示,我在C#中使用扩展方法blogged a handy solution。请注意,这与向查询中的每个表添加nolock提示相同。