use*_*627 5 c# linq automapper
试图让查询起作用,但老实说,我不确定如何(或者甚至可能)进行查询,因为我尝试过的一切都没有奏效。
一共查询6个表:Person、PersonVote、PersonCategory、Category、City、FirstAdminDivision。
PersonVote 是一个用户评论表,包含一个名为 Vote 的列,它是一个接受 1-5 值的小数(5 是“最佳”)。FirstAdminDivision 将是美国各州的同义词,例如加利福尼亚。Person 表有一个名为 CityId 的列,它是 City 的外键。我认为其他表格大多是不言自明的,因此除非需要,否则我不会发表评论。
我的目标是创建一个查询,该查询返回“最受欢迎”人员的列表,该列表将基于 PersonVote 表上特定人员的所有投票的平均值。例如,如果一个人有 3 票并且所有 3 票都是“5”,那么他们将在列表中排在第一位......此时并不真正关心二级排序......例如......就像大多数投票一样平局会“赢”。
我在没有 AutoMapper 的情况下也能工作,但我喜欢 AM 使用 ProjectTo 扩展方法进行投影的能力,因为代码非常干净和可读,如果可能的话,我更愿意使用这种方法,但没有任何运气让它工作。
这是我所拥有的确实有效......所以基本上,我想看看这是否可以用 ProjectTo 而不是 LINQ 的 Select 方法。
List<PersonModel> people = db.People
.GroupBy(x => x.PersonId)
.Select(x => new PersonModel
{
PersonId = x.FirstOrDefault().PersonId,
Name = x.FirstOrDefault().Name,
LocationDisplay = x.FirstOrDefault().City.Name + ", " + x.FirstOrDefault().City.FirstAdminDivision.Name,
AverageVote = x.FirstOrDefault().PersonVotes.Average(y => y.Vote),
Categories = x.FirstOrDefault().PersonCategories.Select(y => new CategoryModel
{
CategoryId = y.CategoryId,
Name = y.Category.Name
}).ToList()
})
.OrderByDescending(x => x.AverageVote)
.ToList();
Run Code Online (Sandbox Code Playgroud)
By looking at your code sample I tried to determine what your models would be in order to setup an example. I only implemented using a few of the properties to show the functionality:
public class People
{
public int PeronId { get; set; }
public string Name { get; set; }
public City City { get; set; }
public IList<PersonVotes> PersonVoes { get; set; }
}
public class PersonVotes
{
public int Vote { get; set; }
}
public class City
{
public string Name { get; set; }
}
public class FirstAdminDivision
{
public string Name { get; set; }
}
public class PersonModel
{
public int PersonId { get; set; }
public string Name { get; set; }
public string LocationDisplay { get; set; }
public double AverageVote { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
To use the ProjectTo extension I then initialize AM through the static API:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<IEnumerable<People>, PersonModel>()
.ForMember(
model => model.LocationDisplay,
conf => conf.MapFrom(p => p.FirstOrDefault().City.Name))
.ForMember(
model => model.AverageVote,
conf => conf.MapFrom(p => p.FirstOrDefault().PersonVoes.Average(votes => votes.Vote)));
});
Run Code Online (Sandbox Code Playgroud)
So given the following object:
var people = new List<People>()
{
new People
{
PeronId = 1,
City = new City
{
Name = "XXXX"
},
PersonVoes = new List<PersonVotes>
{
new PersonVotes
{
Vote = 4
},
new PersonVotes
{
Vote = 3
}
}
}
};
Run Code Online (Sandbox Code Playgroud)
I would then a have query:
var result = people
.GroupBy(p => p.PeronId)
.Select(peoples => peoples)
.AsQueryable()
.ProjectTo<PersonModel>();
Run Code Online (Sandbox Code Playgroud)
I'm just using in memory objects so that is why I convert to IQueryable to use the ProjectTo extension method in AM.
I'm hoping this was what you're looking for. Cheers,
UPDATED FOR LINQ TO ENTITIES QUERY:
var result = db.People
.GroupBy(p => p.PersonId)
.ProjectTo<PersonModel>(base.ConfigProvider) // AM requires me to pass Mapping Provider here.
.OrderByDescending(x => x.AverageVote)
.ToList();
Run Code Online (Sandbox Code Playgroud)