C# 复杂linq到实体查询
我有一个EF模型,有三个表,C# 复杂linq到实体查询,c#,linq,entity-framework,linq-to-entities,C#,Linq,Entity Framework,Linq To Entities,我有一个EF模型,有三个表,Artist,Movie和Movie\u Artist\u Job。 Movie\u Artist\u Job只是一个外键表: MovieId,ArtistId,JobId. 我试图得到这样的结果: 艺人名称1,电影1 艺人名称1、电影2 艺人名称2,电影1 艺人名称2、电影3 等等 现在,我正在这样做: var query = ( from items in _objEntities.Movie_Artist_Job where items.Art
Artist
,Movie
和Movie\u Artist\u Job
。
Movie\u Artist\u Job
只是一个外键表:
MovieId,ArtistId,JobId.
我试图得到这样的结果:
艺人名称1,电影1
艺人名称1、电影2
艺人名称2,电影1
艺人名称2、电影3
等等
现在,我正在这样做:
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);
}
}
}
}
var查询=(
来自_objenties.Movie\u Artist\u Job中的项目
其中items.Artist.FulleName!=string.Empty
选择items.Artist.FulleName).Distinct();
列表项=新列表();
foreach(查询中的字符串全名)
{
变量匹配=(
来自电影中的对象。电影艺术家的工作
其中movie.Artist.FulleName==fullName
选择电影。电影)
.Distinct();
如果(匹配.Count()>0)
{
foreach(电影匹配)
{
if(movies!=null&&movies.IsDeleted==false)
{
新的ThumbItem(全名,movies.title);
}
}
}
}
这是可行的,但需要很长时间
有什么线索可以证明这一点吗
非常感谢您的帮助。您正在以一种有点尴尬的方式处理许多关系。更简单的方法是使用主键将此表设置为如下所示
public class Movie_Artist_Job
{
public int Id { get; set; }
public Artist Artist { get; set; }
public Movie Movie { get; set; }
}
然后,只需调用
db.Movie\u Artist\u Job.ToList()
我尝试复制您提到的db:-
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;
它工作得非常快,没有采取任何措施,我认为您的问题是,您将控件的匹配和创建分离为不同的步骤,而不是使用select into entity执行join语句;这是一个耗时的动作
编辑:-
评论中的新问题:-需要同一查询中每位艺术家的电影数量吗
只需在一个代码之后添加此代码,即可获得DB往返的结果:-
var ListByArtist = Thumbs.ToList().GroupBy(l => l.ArtistName).Select(lg => new
{
Artist = lg.Key,
NumberOfMovies = lg.Count()
});
在循环中查询数据库。这将导致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();
var查询=(
来自_objenties.Movie\u Artist\u Job中的项目
其中items.Artist.FulleName!=string.Empty
选择项目。艺术家。全名)
.Distinct();
变量匹配=
从查询中的全名
来自电影中的对象。电影艺术家的工作
其中movie.Artist.FulleName==fullName
哪里电影被删除了
选择新建{movie.fullName,movie.title})
.Distinct()
.ToArray();
列表项=(
从电影中配对
选择新的拇指项(movie.fullName、movie.title))
.ToList();
您试图做的就是所谓的“旋转”,您应该看看如何在正确构建的EF模型上实现这一点
顺便说一句,EF的要点是能够以自然的面向对象方式编写查询,也就是说,你不应该太在意C端的“电影艺术家工作”表(调用艺术家。电影应该返回给定艺术家的电影列表)你试过分析这个吗?您可以使用SQL探查器找出哪些查询是在后台执行的。我打赌是1。执行了太多的查询,结果为2。您缺少一些数据库索引。同意您的方法,但我不会首先使用代码,因此我必须管理现有的Db架构。您好,OmarQa,您的代码触礁:)非常感谢您的快速帮助。有没有机会通过您的查询获得每位艺术家的电影数量?您好,谢谢您的补充,您可以通过从“拇指项目”列表中选择一个按计数分组的项目来获得每位艺术家的电影数量,我已经编辑了我的答案,您可以查看,希望这是您需要的,祝您好运:)谢谢您的代码,但是OmarQa的答案非常快。顺便说一句,非常感谢你花时间帮助我。