我有一个SQL查询并想将其转换为LINQ语句,并且在从未为Linq语句工作之前,请先帮助我,谢谢
SELECT c.* , v.*
FROM UserEnrolleds u
INNER JOIN Courses c ON u.CourseId = c.id
INNEr JOIN Videos v ON v.CourseID = c.Id
WHERE u.UsersID = '8851d572-eaff-4a84-9ec8-aa144fecfea2'
答案 0 :(得分:1)
显然您有三个表:“课程”,“视频”和“用户注册”。
课程与UserEnrolled之间存在关系,可能是一对多的关系:每个课程都有零个或多个UserEnrolled,每个UserEnrolled都完全属于一个课程,即带有Course.Id的课程,即外键UserEnrolled .CourseId指向。
类似地,视频和课程之间似乎存在一对多的关系:每个视频都有一个外键Video.CourseId属于它所属的课程。
在我看来,您想要由ID为“ 8851d572-eaff ...”的用户注册的课程和视频。
您计划使用UserEnrolleds-课程-视频的内部联接来做到这一点。
如果使用实体框架,则可以使用两种方法。您可以使用virtual ICollection
属性,也可以自己加入。
通常,我发现ICollection
的使用更容易且更具吸引力,但让我们首先关注您的问题。
为此,我将使用Queryable.Join的重载之一
var result = dbContext.UserEnrolleds // get table UserEnrolleds
// keep only the UserEnrolleds with the mentioned UsersId:
.Where(userEnrolled => userEnrolled.UsersId = "8851...")
.Join(dbContext.Courses, // join with table Courses,
userEnrolled => userEnrolled.CourseId, // from every userEnrolled take the CourseId
course => course.Id, // from every course take the Id
(userEnrolled, Course) => new // remember the matching items for the next join
{
UserEnrolled = userEnrolled,
Course = Course,
})
.Join(dbContext.Videos, // join with the Videos table
joinResult => joinResult.Course.Id, // from the previous Join take the Course Id
video => video.CourseId, // from the video take the CourseId
(joinResult, video) => new // when they match, make one new object
{
UserEnrolled => joinResult.UserEnrolled,
Course => joinResult.Course,
Video => video,
})
加入后,使用“选择”仅查询您实际打算使用的属性。
.Select(joinResult => new
{
Course = new
{
Id = joinResult.Course.Id,
Name = joinResult.Course.Name,
...
},
Video = new
{
Id = joinResult.Video.Id,
Name = joinResult.Video.Name,
...
}
UserEnrolled = ...
});
如果您要查询完整的课程和视频:
.Select(joinResult => new
{
Course = joinResult.Course,
Video = joinResult.Video,
})
请注意,尽管您将转移一些您可能不会使用的属性,尤其是外键。
当然,您可以在联接的最后一个参数(resultSelector)中进行选择。我没有这样做,是为了使其更容易理解。
通常,如果您具有一对多关系,则希望执行GroupJoin而不是Join:您需要所有“有关其视频的课程”。
所以不是表格:
Course 1 - Video 10
Course 1 - Video 11
Course 1 - Video 12
Course 2 - Video 13
Course 2 - Video 14
Course 3 - Video 15
您想要一张桌子:
Course 1 with its Videos 10, 11, and 12
Course 2 with its Videos 13, and 14
Course 3 with its one and only Video 15
Course 4 has no Video at all.
如果您更喜欢“课程与他们的视频”(也许还有UserEnrolleds的一些课程),那么使用virtual ICollection
而不是自己加入就更容易了。
如果您遵循entity framework code first conventions,则将具有与以下类似的类:
class Course
{
public int Id {get; set;}
public string Name {get; set;}
...
// Every Course has zero or more Videos:
public virtual ICollection<Video> Videos {get; set;}
// Every Course has zero or more UserEnrolleds:
public virtual ICollection<UserEnrolled> UserEnrolleds {get; set;}
}
public class Video
{
public int Id {get; set;}
public string Name {get; set;}
...
// every Video belongs to exactly one Course, using foreign key:
public int CourseId {get; set;}
public virtual Course Course {get; set;}
}
UserEnrolled与视频类似:
public class UserEnrolled
{
public int Id {get; set;}
public string UsersId {get; set;}
...
// every Video belongs to exactly one Course, using foreign key:
public int CourseId {get; set;}
public virtual Course Course {get; set;}
}
在实体框架中,表的列由非虚拟属性表示。虚拟属性表示表之间的关系(一对多,多对多,...)
外键是表中的实列,因此它们是非虚拟的
出于完整性考虑,DbContext:
class MyDbContext : DbContext
{
public DbSet<Course> Courses {get; set;}
public DbSet<Video> Videos {get; set;}
public DbSet<UserEnrolled> UserEnrolleds {get; set;}
}
这是实体框架检测表,表中的列以及它们之间的关系所需要知道的全部内容。它还将为您创建和使用主键和外键。
现在获取由用户注册的ID为“ 8851d572-eaff ...”(=至少具有一个UserEnrolled的UsersId等于“ 8851d572-eaff ...”的用户的所有课程,包括其视频) ”),请使用以下查询:
var coursesAndVideosEnrolledByUser = dbContext.Courses
// keep only the Courses that are enrolled by user with Id "8851..."
.Where(course => course.UserEnrolleds
.Any(userEnrolled => userEnrolled.UsersId = "8851d572-eaff..."))
.Select(course => new
{
Id = course.Id,
Name = course.Name,
...
Videos = course.Videos,
});
您是否同意,如果要让每个课程及其视频都由某个用户参加的话,这看起来自然吗?
加分点:如果该用户参加的课程没有视频,您仍然会在结果中得到它们。您将无法通过内部联接来获得它们!
答案 1 :(得分:0)
假设变量db是您的数据库尝试;
var qdResult =
from u in db.UserEnrolleds
join c in db.Courses on u.CourseID equals c.id
join v in db.Videos on c.Id equals v.CourseID
where u.UsersID = '8851d572-eaff-4a84-9ec8-aa144fecfea2'
select c, v