我的下面的Sql工作得很好,但现在我想加入另一个有共同密钥的文件。我想加入的文件可能有一对多记录,任何建议
这是我的代码:
var regPoints = (from x in db.CertPoints
join y in db.CommunityPts on x.PointId equals y.PointId into z
from t in
(from r in z
where r.CommunityId == id select r).DefaultIfEmpty()
where x.TypeId == 1
select new Points
{
pointId = x.PointId,
pointsDescription = x.PointDescription,
points = x.Points,
dateApplied = t.DateApplied,
pointsEarned = t.PointsEarned,
pointsPending = t.Pending ? true : false,
pointsApproved = t.Approved ? true : false,
notes = t.Notes
}).AsEnumerable();
新连接将是一对多记录,其中CommunityPts中的密钥是Id,我想要加入的文件是文件链接列表" CommunityPtsDocs"用外键CommnunityPtId。我如何将它添加到上面的上述sql语句中?
答案 0 :(得分:1)
以下修改将有助于实现任务,虽然我更喜欢Fluent语法,因为在我看来实现相同的更清晰,尽管我没有在Select语句中选择CommunityPtsDocs
中的任何列
var regPoints = (from x in CertPoints
join y in CommunityPts on x.PointId equals y.PointId
join s in CommunityPtsDocs on y.Id equals s.CommnunityPtId into k
from t in (from r in k where r.CommunityId == id select r).DefaultIfEmpty()
where x.TypeId == 1
select new Points
{
pointId = x.PointId,
pointsDescription = x.PointDescription,
points = x.Points,
dateApplied = t.DateApplied,
pointsEarned = t.PointsEarned,
pointsPending = t.Pending ? true : false,
pointsApproved = t.Approved ? true : false,
notes = t.Notes
}).AsEnumerable();
答案 1 :(得分:1)
有时我觉得我是导航属性的传道者(幸运的是,我不是唯一一个)。
你接受的答案是好的,它完成了这项工作。但是使用任何ORM(如Entity Framework或LINQ-to-SQL),您应尽可能避免使用join
语句。它冗长且容易出错。它会导致重复的代码,并且错误地加入错误的属性太容易了。
您的班级CertPoint
可以有0..1-n导航属性CommunityPts
(列表),CommunityPt
可以有1-n导航属性CommunityPtsDocs
(也是一个清单)。如果您正在使用LINQ-to-SQL,那么他们可能已经存在但您还没有意识到它们。如果您首先使用实体框架代码,则应自行添加它们。
拥有这些导航属性后,您的代码将如下所示:
from cert in CertPoints
from comm in cert.CommunityPts.DefaultIfEmpty()
from doc in comm.CommunityPtsDocs
where comm.CommunityId == id && cert.TypeId == 1
select new Points
{
pointId = cert.PointId,
pointsDescription = cert.PointDescription,
points = cert.Points,
dateApplied = comm.DateApplied,
pointsEarned = comm.PointsEarned,
pointsPending = comm.Pending ? true : false,
pointsApproved = comm.Approved ? true : false,
notes = comm.Notes,
something = doc.Something
})
现在,ORM将使用正确的连接将其转换为SQL,并且您的代码看起来更清晰(请注意,我也更喜欢更有意义的范围变量名称)。