我目前正在使用Entity Framework进行数据库访问,但想看看Dapper.我有这样的课程:
public class Course{
public string Title{get;set;}
public IList<Location> Locations {get;set;}
...
}
public class Location{
public string Name {get;set;}
...
}
Run Code Online (Sandbox Code Playgroud)
因此,可以在多个地点教授一门课程.实体框架为我执行映射,因此我的Course对象填充了一个位置列表.我如何与Dapper一起讨论这个问题,它是否可能,或者我必须在几个查询步骤中执行此操作?
Jer*_*n K 159
或者,您可以将一个查询与查找一起使用:
var lookup = new Dictionary<int, Course>();
conn.Query<Course, Location, Course>(@"
SELECT c.*, l.*
FROM Course c
INNER JOIN Location l ON c.LocationId = l.Id
", (c, l) => {
Course course;
if (!lookup.TryGetValue(c.Id, out course))
lookup.Add(c.Id, course = c);
if (course.Locations == null)
course.Locations = new List<Location>();
course.Locations.Add(l); /* Add locations to course */
return course;
}).AsQueryable();
var resultList = lookup.Values;
Run Code Online (Sandbox Code Playgroud)
请参见https://www.tritac.com/blog/dappernet-by-example/
Sam*_*ron 48
Dapper并不是一个完整的ORM它不会处理魔法生成的查询等.
对于您的特定示例,以下可能会起作用:
var courses = cnn.Query<Course>("select * from Courses where Category = 1 Order by CreationDate");
Run Code Online (Sandbox Code Playgroud)
var mappings = cnn.Query<CourseLocation>(
"select * from CourseLocations where CourseId in @Ids",
new {Ids = courses.Select(c => c.Id).Distinct()});
Run Code Online (Sandbox Code Playgroud)
var locations = cnn.Query<Location>(
"select * from Locations where Id in @Ids",
new {Ids = mappings.Select(m => m.LocationId).Distinct()}
);
Run Code Online (Sandbox Code Playgroud)
将此信息留给读者,您可以创建一些地图并遍历填充位置的课程.
需要注意的in
伎俩将工作,如果你有小于2100个查询(SQL Server)的,如果你有更多你可能想查询修改为select * from CourseLocations where CourseId in (select Id from Courses ... )
如果这是你可以使用以及抽出一个全力以赴的结果的情况下QueryMultiple
tch*_*dze 31
不需要lookup
字典
var coursesWithLocations =
conn.Query<Course, Location, Course>(@"
SELECT c.*, l.*
FROM Course c
INNER JOIN Location l ON c.LocationId = l.Id
", (course, location) => {
course.Locations = course.Locations ?? new List<Location>();
course.Locations.Add(location);
return course;
}).AsQueryable();
Run Code Online (Sandbox Code Playgroud)
Dan*_*enz 27
我知道我已经迟到了,但还有另一种选择.您可以在此处使用QueryMultiple.像这样的东西:
var results = cnn.QueryMultiple(@"
SELECT *
FROM Courses
WHERE Category = 1
ORDER BY CreationDate
;
SELECT A.*
,B.CourseId
FROM Locations A
INNER JOIN CourseLocations B
ON A.LocationId = B.LocationId
INNER JOIN Course C
ON B.CourseId = B.CourseId
AND C.Category = 1
");
var courses = results.Read<Course>();
var locations = results.Read<Location>(); //(Location will have that extra CourseId on it for the next part)
foreach (var course in courses) {
course.Locations = locations.Where(a => a.CourseId == course.CourseId).ToList();
}
Run Code Online (Sandbox Code Playgroud)
很抱歉迟到了(像往常一样)。对我来说,在性能和可读性方面Dictionary
,像 Jeroen K 那样使用 更容易。此外,为了避免跨位置的标题乘法,我使用Distinct()
删除潜在的重复:
string query = @"SELECT c.*, l.*
FROM Course c
INNER JOIN Location l ON c.LocationId = l.Id";
using (SqlConnection conn = DB.getConnection())
{
conn.Open();
var courseDictionary = new Dictionary<Guid, Course>();
var list = conn.Query<Course, Location, Course>(
query,
(course, location) =>
{
if (!courseDictionary.TryGetValue(course.Id, out Course courseEntry))
{
courseEntry = course;
courseEntry.Locations = courseEntry.Locations ?? new List<Location>();
courseDictionary.Add(courseEntry.Id, courseEntry);
}
courseEntry.Locations.Add(location);
return courseEntry;
},
splitOn: "Id")
.Distinct()
.ToList();
return list;
}
Run Code Online (Sandbox Code Playgroud)
小智 6
缺了点什么。如果不指定Locations
SQL 查询中的每个字段,Location
则无法填充对象。看一看:
var lookup = new Dictionary<int, Course>()
conn.Query<Course, Location, Course>(@"
SELECT c.*, l.Name, l.otherField, l.secondField
FROM Course c
INNER JOIN Location l ON c.LocationId = l.Id
", (c, l) => {
Course course;
if (!lookup.TryGetValue(c.Id, out course)) {
lookup.Add(c.Id, course = c);
}
if (course.Locations == null)
course.Locations = new List<Location>();
course.Locations.Add(a);
return course;
},
).AsQueryable();
var resultList = lookup.Values;
Run Code Online (Sandbox Code Playgroud)
l.*
在查询中使用时,我有位置列表但没有数据。
归档时间: |
|
查看次数: |
71685 次 |
最近记录: |