复杂的实体链接查询

本文关键字:查询 链接 实体 复杂 | 更新日期: 2023-09-27 18:19:17

我有一个EF模型有3个表,Artist, MovieMovie_Artist_JobMovie_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: -

  1. 电影
  2. <
  3. 工作/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应该返回给定艺术家的电影列表)