【问题标题】:Problem returning an IEnumerable<T>/IList<T>返回 IEnumerable<T>/IList<T> 的问题
【发布时间】:2011-03-17 19:58:29
【问题描述】:

我无法返回 IEnumerable 和 IList,我做不到! 我正在使用带有 POCO 的 EF 4

这是整个方法:

//public IList<Genre> GetGenresByGame(int gameId)
public IEnumerable<Genre> GetGenresByGame(int gameId)
    {
        using(var ctx = new XContext())
        {
            var results =
                    from t0 in ctx.GameGenres
                    join t1 in ctx.GenreCultureDetails on t0.GenreId equals t1.GenreId
                    where t0.GameId == gameId && t1.CultureId == _cultureId
                    select new Genre
                    {
                        GenreId = t0.GenreId,
                        GenreName = t1.GenreName

                    };

            return results.ToList(); 
        }
    }

我尝试了我在网上找到的不同方法..但无法成功!

问题 2: 我看到 Julie 的截屏视频,说“在使用 EF4 时,您应该始终返回 ICollection”。

对此有什么想法吗?

BR

编辑: 当我在调试模式下加载页面时,出现以下错误:The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. OR The entity or complex type 'XModel.Genre' cannot be constructed in a LINQ to Entities query

【问题讨论】:

  • 只是一个随机问题,但您的数据库中是否存在流派?如果是这样,你为什么不直接选择呢?
  • 是的,数据库中确实存在流派。选择,什么意思?
  • 见下文,如果您提供有关表结构的更多信息,我可以更新详细信息。
  • @Nix 你需要什么信息?我得到了三个表,Genres (GenreId)、GameGenres (MAP GenreId, GameId) 和 GenreCultureDetail (CultureId, GenreId, GenreName)

标签: linq entity-framework-4 ienumerable poco


【解决方案1】:

Genre 不能是 L2EF 类型。试试这个:

public IEnumerable<Genre> GetGenresByGame(int gameId)
{
    using(var ctx = new XContext())
    {
        var resultList =
                from t0 in ctx.GameGenres
                join t1 in ctx.GenreCultureDetails on t0.GenreId equals t1.GenreId
                where t0.GameId == gameId && t1.CultureId == _cultureId
                select new { t0.GenreId, t1.GenreName };
        var genres = resultList.AsEnumerable().Select(o => new Genre
                     {
                         GenreId = o.GenreId,
                         GenreName = o.GenreName
                     });
        return genres.ToList();
    }
}

【讨论】:

  • 我相信最好先使用AsEnumerable(你有ToList),然后在最后使用ToList
  • @Snowbear: AsEnumerable() 不会执行查询(事实上,它不会做任何事情),因此会导致 OP 遇到同样的问题。见stackoverflow.com/questions/3389855/…
  • @BlueRaja,正确,此时您不需要立即执行,您需要在该方法中的某处执行。您只需将下一个Select 视为IEnumerable.Select 而不是IQueryable.SelectAsEnumerable 即可。
  • @BlueRaja,谢谢,但你仍然需要ToList,否则它根本不会被执行。我只是想说ToList 可以比原来移动几行。它将使您的方法返回常规的List 而不是List,并像您最初那样在其上进行投影。无论如何,您的答案似乎是正确的。
  • ANSWER 1 在我添加 ToList() 时起作用,返回 Genres.ToList();
【解决方案2】:

首先,如果 Genre 在数据库中,您应该选择它吗?如果您有来自 Genre->GenreCultureDetails 的 FK,请告诉我,我可以更新以下内容,但从外观上看,您可以这样做:

using(var ctx = new XContext())
{
    var results =
            from g in ctx.Genre
            join gcd in ctx.GenreCultureDetails on g.GenreId equals gcd.GenreId
            where g.GameId == gameId && gcd.CultureId == _cultureId
            select g;


    return result.ToList();
}

或者继续沿着你的路径选择它们到一个令人讨厌的类型,然后复制它们。如果你愿意,你可以使用 select 而不是 convertall。

IList<Genre> returnMe = Null;
using(var ctx = new XContext())
{
    var results =
            from t0 in ctx.GameGenres
            join t1 in ctx.GenreCultureDetails on t0.GenreId equals t1.GenreId
            where t0.GameId == gameId && t1.CultureId == _cultureId
            select new
            {
                GenreId = t0.GenreId,
                GenreName = t1.GenreName

            };

    returnMe  = results.ToList().ConvertAll(x=>new Genre(){
                           GenreId = x.GenreId,
                           GenreName = x.GenreName
                           }
          );
}
return returnMe;

【讨论】:

  • 你的两个改变有什么意义? AsEnumerable 无论如何都不会影响它,没有()Genre 只是一个语法糖。
  • 括号不会改变任何东西。 new Genre() { GenreID = xyz };new Genre { GenreID = xyz }; 是一样的。
  • 这很有趣,但现在你应该使用AsEnumerable 而不是ToList()
  • AsEnumerable 不会创建无用的List
  • ANSWER 0 给了我:无法将类型 'System.Collections.Generic.List' 隐式转换为 'System.Linq.IQueryable'
猜你喜欢
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多