复杂的实体链接查询
本文关键字:查询 链接 实体 复杂 | 更新日期: 2023-09-27 18:19:17
我有一个EF模型有3个表,Artist
, Movie
和Movie_Artist_Job
。Movie_Artist_Job
只是一个外键表:
MovieId,ArtistId,JobId.
我想得到这样的结果:
ArtistName1, Movie1
ArtistName1, Movie2
Artistname2, Movie1
Artistname2, Movie3
等等……
现在我正在做这个:
var query = (
from items in _objEntities.Movie_Artist_Job
where items.Artist.FulleName != string.Empty
select items.Artist.FulleName).Distinct<string>();
List<ThumbItem> Items = new List<ThumbItem>();
foreach (string fullName in query)
{
var matching = (
from movie in _objEntities.Movie_Artist_Job
where movie.Artist.FulleName == fullName
select movie.Movie)
.Distinct<Movie>();
if (matching.Count() > 0)
{
foreach (Movie movies in matching)
{
if (movies != null && movies.IsDeleted == false)
{
new ThumbItem(fullName, movies.title);
}
}
}
}
它是有效的,但需要很长时间…
有什么好办法吗?
非常感谢你的帮助
在循环中查询数据库。这将导致N + 1个查询。试着将你的代码重写为如下内容:
var query = (
from items in _objEntities.Movie_Artist_Job
where items.Artist.FulleName != string.Empty
select items.Artist.FulleName)
.Distinct();
var matching =
from fullName in query
from movie in _objEntities.Movie_Artist_Job
where movie.Artist.FulleName == fullName
where !movies.IsDeleted
select new { movie.fullName, movie.title })
.Distinct()
.ToArray();
List<ThumbItem> Items = (
from movie in matching
select new ThumbItem(movie.fullName, movie.title))
.ToList();
我试图复制您提到的DB: -
- 电影
- <
- 工作/gh>
和i添加一个实体类thumbItem,如下所示;选择项目到:-
internal class ThumbItem
{
public string ArtistName { set; get; }
public string MovieName { set; get; }
}
和我已经执行了以下函数来获得您要求的结果:-
MoviesEntities context = new MoviesEntities();
var Thumbs = from artist in context.Artists
join job in context.Jobs on artist.ID equals job.ArtistID
join movie in context.Movies on job.MovieID equals movie.ID
select new ThumbItem()
{
ArtistName = artist.Name,
MovieName = movie.Name
};
dataGridView1.DataSource = Thumbs;
它工作得非常快,没有采取任何措施,我认为你的问题是你将匹配和控件的创建分开到不同的步骤,而不是执行与选择到实体的连接语句;这是一个耗时的动作。
编辑:
来自评论的新问题:-需要从同一查询中获得每个艺术家的电影数量?
只需将下面的代码添加到后面,然后它就会得到DB往返的结果:-
var ListByArtist = Thumbs.ToList().GroupBy(l => l.ArtistName).Select(lg => new
{
Artist = lg.Key,
NumberOfMovies = lg.Count()
});
你处理很多关系的方式有点尴尬。更简单的方法是将该表设置为主键
,如下所示public class Movie_Artist_Job
{
public int Id { get; set; }
public Artist Artist { get; set; }
public Movie Movie { get; set; }
}
然后,调用db.Movie_Artist_Job.ToList()
你正在尝试做的是所谓的"旋转",你应该看看Linq扩展库如何在正确构建EF模型上实现这一点。
作为旁注,EF的所有要点是能够以自然的面向对象的方式编写查询,也就是说,你不应该太关心c#方面的"Movie_Artist_Job"表(调用艺术家)。Movies应该返回给定艺术家的电影列表)