0

我正在尝试让 Where In 子句与 linq to 实体一起使用并遇到问题。我的问题是我有几个不同实体的列表,我想从这些列表中选择一组游戏实体,基本上为它们设置一个 SQL WHERE IN 子句。问题是实体列表正在与游戏实体的相关实体进行比较,这些实体具有多对多关系。我已经做了很多研究并尝试了很多解决方案来解决这个问题,但就是不能完全正确,我非常感谢 stackoverflow 社区的一些帮助。

提前致谢。

编辑:

我试过这样做而不是工会:

     var relatedGames = from game in ugdb.Games
                        where game.Developers.Any(d => relatedDevelopers.Any(r => r.DeveloperID == d.DeveloperID))
                        || game.Publishers.Any(d => relatedPublishers.Any(r => r.PublisherID == d.PublisherID))
                        || game.Genres.Any(d => relatedGenres.Any(r => r.GenreID == d.GenreID))
                        select game;

与工会和这个我收到以下错误消息:

base {System.SystemException} = {“无法创建“UltimateGameDB.Domain.Entities.Developer”类型的常量值。在此上下文中仅支持原始类型(“例如 Int32、String 和 Guid”)。”}

有谁知道如何在没有

我当前的代码:

  public IQueryable<Video> GetSimilarVideos(Guid videoId)
  {
     IQueryable<Video> result = null;
     List<Video> similarVideoList = null;

     Video currentVideo = ugdb.Videos.Find(videoId);

     List<Genre> relatedGenres = new List<Genre>();
     List<Developer> relatedDevelopers = new List<Developer>();
     List<Publisher> relatedPublishers = new List<Publisher>();

     foreach (var game in currentVideo.Games)
     {
        relatedDevelopers.AddRange(game.Developers);
        relatedPublishers.AddRange(game.Publishers);
        relatedGenres.AddRange(game.Genres);
     }

     relatedDevelopers = relatedDevelopers.Distinct().ToList<Developer>();
     relatedPublishers = relatedPublishers.Distinct().ToList<Publisher>();
     relatedGenres = relatedGenres.Distinct().ToList<Genre>();

     //This is the piece I am having trouble with!
     var relatedGames = from game in ugdb.Games
                        where game.Developers.Union(relatedDevelopers).Count() > 0
                          || game.Genres.Union(relatedGenres).Count() > 0
                          || game.Publishers.Union(relatedPublishers).Count() > 0
                        select game;

     foreach (var game in relatedGames)
     {
        similarVideoList.AddRange(game.Videos.Where(v => v.VideoType.Equals(currentVideo.VideoType)));
     }

     result = similarVideoList.Distinct().AsQueryable<Video>();

     return result;
  }
4

2 回答 2

3

您不能传递本地实体 - 它们不会转换为 sql,在您的情况下是相关的开发人员。Linq to Entities 无法转换relatedDevelopers.Contains为 Sql IN

您可以投射游戏列表并在内存中进行调用,这样就不必将其转换为 sql - 这更容易,但如果您的数据库很大,加载它可能会很糟糕,只需ToList()在最后添加的ugdb.Games

 var relatedGames = from game in ugdb.Games.ToList()
                    where game.Developers.Any(d => relatedDevelopers.Any(r => r.DeveloperID == d.DeveloperID))
                    || game.Publishers.Any(d => relatedPublishers.Any(r => r.PublisherID == d.PublisherID))
                    || game.Genres.Any(d => relatedGenres.Any(r => r.GenreID == d.GenreID))
                    select game;

或者,您可以创建一个 Id 列表并传递它,因为这是 SQL 可以识别的原始类型:

     var relatedDevelopers = currentVideo.Games.SelectMany( g => g.Developers ).Select( g => g.DeveloperID ).ToArray();
     var relatedPublishers = currentVideo.Games.SelectMany( g => g.Developers ).Select( g => g.DeveloperID ).ToArray();
     var relatedGenres = currentVideo.Games.SelectMany( g => g.Developers ).Select( g => g.DeveloperID ).ToArray();


     //This is the piece I am having trouble with!
     var relatedGames = from game in ugdb.Games
                        where game.Developers.Any( d => relatedDevelopers.Contains(d.DeveloperID) )
                        || game.Publishers.Any( d => relatedPublishers.Contains(d.PublisherID))
                        || game.Genres.Any( d => relatedGenres.Contains(d.GenreID) )
                        select game;
于 2012-08-24T03:24:33.360 回答
2

该模式通常是使用嵌套的Any,或Any带有Contains

var relatedDeveloperIds = relatedDevelopers.Select(r => r.Id).ToList();
game.Developers.Any(d => relatedDeveloperIds.Contains(d.Id))
于 2012-08-23T01:00:08.833 回答