我有以下的类,我有一个从数据库中获取数据的服务。
public class Course
{
public string CourseNumber { get; set; }
public List<PriceGroup> PriceGroups { get; set; }
}
public class PriceGroup
{
public int Id { get; set; }
public string CourseNumber { get; set; }
}
我有一个从数据库中获取数据的服务。课程是一个 IEnumerable<Course>
而priceGroups是一个 IEnumerable<PriceGroup>
. 正如你在课程类中看到的,一个课程有一个 List<PriceGroup>
. 我需要以某种方式将每个价格组添加到 IEnumerable<PriceGroup>
列表中的每门课程 IEnumerable<Course>
如果它们在变量上吻合 CourseNumber
. 因此,我将最终与一个正确的课程包含正确的。List<PriceGroup>
's
public async Task<IEnumerable<Course>> GetAllAsync()
{
//courses is an IEnumerable<Course>
var courses = await _courseRepository.GetAllAsync();
//priceGroups is an IEnumerable<PriceGroup>
var priceGroups = await _coursePriceGroupRepository.GetAllAsync();
courses.GroupJoin(priceGroups, c => c.PriceGroups.Select(i => i.CourseNumber), pg => pg.CourseNumber, (c, pg) => new
{
});
return await courses;
}
为了做到这一点,我曾尝试过做GroupJoin,但没有成功。我还没有完成这个尝试,因为我在心理上完全卡住了。也许我想做的事情是不可能通过GroupJoin实现的。有谁知道有什么方法可以实现我所需要的?
所以您需要所有(或部分)课程,每个课程都有所有(或部分)价格群。
课程和PriceGroups之间有一个直接的一对多关系。每一门课程都有零个或多个价格群,每个价格群只属于一门课程,即外键CourseNumber所指的课程。
你说的对,只要你想要项目及其子项目,你就用GroupJoin。
public async Task<IEnumerable<Course>> GetAllAsync()
{
IEnumerable<Course> courses = await _courseRepository.GetAllAsync();
IEnumerable<PriceGroup> priceGroups = await _coursePriceGroupRepository.GetAllAsync();
var queryCoursesWithPriceGroups = courses.GroupJoin( // GroupJoin Courses
priceGroups, // with PriceGroups
course => course.CourseNumber, // from every Course take primary key
priceGroup => priceGroup.CourseNumber, // from every PriceGroup take foreign key
(course, priceGroupsOfThisCourse) => new // from every Course with
{ // its priceGroups make one new
// Select the Course properties you plan to use:
Id = course.Id,
Name = course.Name,
StartDate = course.StartDate,
...
PriceGroups = priceGroupsOfThisCourse.Select(priceGroup => new
{
// Select only the PriceGroup properties that you plan to use
Id = priceGroup.Id,
Name = priceGroup.Name,
...
// not needed, you know the value:
// CourseId = priceGroup.CourseId
})
.ToList(),
});
// Note: this is a query. It is not executed yet!
return await queryCoursesWithPriceGroups.ToListAsync();
//Assuming courseNumber is unique in Courses table
return Courses.Select( c=> { c.PriceGroup=priceGroup.Where(p=>p.CourseNumber==c.CourseNumber).ToList(); return c; });
我做了一个实际的例子,很明显,你应该用仓库的方法代替假方法。
class Program
{
static async void Main(string[] args)
{
var courses = GetAllAsync().Result;
}
private static async Task<IEnumerable<Course>> GetAllAsync()
{
//courses is an IEnumerable<Course>
var courses = await GetCoursesAsync();
//priceGroups is an IEnumerable<PriceGroup>
var priceGroups = await GetPriceGroups();
foreach (var course in courses)
{
foreach (var priceGroup in priceGroups.Where(x => x.CourseNumber == course.CourseNumber))
{
course.PriceGroups.Add(priceGroup);
}
}
return courses;
}
private static async Task<IEnumerable<Course>> GetCoursesAsync()
{
return await Task.FromResult<IEnumerable<Course>>(
new List<Course>() {
new Course{
CourseNumber = "PIZZA1",
PriceGroups = new List<PriceGroup>()
},
new Course{
CourseNumber = "PIZZA2",
PriceGroups = new List<PriceGroup>()
},
new Course{
CourseNumber = "PIZZA3",
PriceGroups = new List<PriceGroup>()
},
}
);
}
private static async Task<IEnumerable<PriceGroup>> GetPriceGroups()
{
return await Task.FromResult<IEnumerable<PriceGroup>>(
new List<PriceGroup>() {
new PriceGroup{
Id = 1,
CourseNumber = "PIZZA1"
},
new PriceGroup{
Id = 2,
CourseNumber = "PIZZA2"
},
new PriceGroup{
Id = 3,
CourseNumber = "PIZZA3"
}
}
);
}
}
public class Course
{
public string CourseNumber { get; set; }
public List<PriceGroup> PriceGroups { get; set; }
}
public class PriceGroup
{
public int Id { get; set; }
public string CourseNumber { get; set; }
}
当你从DB中返回数据时,你应该避免使用IEnumerable,你可能会产生意想不到的行为。我建议你用这种方法。
class Program
{
static void Main(string[] args)
{
var courses = GetAllAsync().Result;
}
private static async Task<List<Course>> GetAllAsync()
{
var courses = await GetCoursesAsync();
var priceGroups = await GetPriceGroups();
courses.ForEach(x => { x.PriceGroups.AddRange(priceGroups.Where(y => y.CourseNumber == x.CourseNumber)); });
return courses;
}
private static async Task<List<Course>> GetCoursesAsync()
{
return await Task.FromResult(
new List<Course>() {
new Course{
CourseNumber = "PIZZA1",
PriceGroups = new List<PriceGroup>()
},
new Course{
CourseNumber = "PIZZA2",
PriceGroups = new List<PriceGroup>()
},
new Course{
CourseNumber = "PIZZA3",
PriceGroups = new List<PriceGroup>()
},
}
);
}
private static async Task<List<PriceGroup>> GetPriceGroups()
{
return await Task.FromResult(
new List<PriceGroup>() {
new PriceGroup{
Id = 1,
CourseNumber = "PIZZA1"
},
new PriceGroup{
Id = 2,
CourseNumber = "PIZZA2"
},
new PriceGroup{
Id = 3,
CourseNumber = "PIZZA3"
}
}
);
}
}
public class Course
{
public string CourseNumber { get; set; }
public List<PriceGroup> PriceGroups { get; set; }
}
public class PriceGroup
{
public int Id { get; set; }
public string CourseNumber { get; set; }
}
我也做了一个使用GroupJoin的版本。
class Program
{
static void Main(string[] args)
{
var courses = GetAllAsync().Result;
}
private static async Task<List<Course>> GetAllAsync()
{
var courses = await GetCoursesAsync();
var priceGroups = await GetPriceGroups();
var groupedData = courses.GroupJoin(priceGroups,
course => course.CourseNumber,
priceGroup => priceGroup.CourseNumber,
(course, priceGroupsCollection) =>
new
{
CourseNumber = course.CourseNumber,
PriceGroups = priceGroupsCollection.ToList()
});
courses.ForEach(x => { x.PriceGroups = groupedData.FirstOrDefault(y => y.CourseNumber == x.CourseNumber)?.PriceGroups ?? new List<PriceGroup>(); });
return courses;
}
private static async Task<List<Course>> GetCoursesAsync()
{
return await Task.FromResult(
new List<Course>() {
new Course{
CourseNumber = "PIZZA1",
PriceGroups = new List<PriceGroup>()
},
new Course{
CourseNumber = "PIZZA2",
PriceGroups = new List<PriceGroup>()
},
new Course{
CourseNumber = "PIZZA3",
PriceGroups = new List<PriceGroup>()
},
}
);
}
private static async Task<List<PriceGroup>> GetPriceGroups()
{
return await Task.FromResult(
new List<PriceGroup>() {
new PriceGroup{
Id = 1,
CourseNumber = "PIZZA1"
},
new PriceGroup{
Id = 2,
CourseNumber = "PIZZA2"
},
new PriceGroup{
Id = 3,
CourseNumber = "PIZZA3"
},
new PriceGroup{
Id = 4,
CourseNumber = "PIZZA1"
}
}
);
}
}
public class Course
{
public string CourseNumber { get; set; }
public List<PriceGroup> PriceGroups { get; set; }
}
public class PriceGroup
{
public int Id { get; set; }
public string CourseNumber { get; set; }
}