EF:获取包含列表作为属性的对象

时间:2013-06-08 14:20:32

标签: c# entity-framework entity-framework-5

我有以下课程:

public class DbCatalogEntry
{
    public int id { get; set; }
    private string filename;
    public long size { get; set; }
    public int duration { get; set; }
    public int height { get; set; }
    public int width { get; set; }
    public string vcodec { get; set; }
    public List<CatalogAudioStreamEntry> audiostreams { get; set; }
    public string imdbId { get; set; }
    public int ownedByUser { get; set; }
    public string mxHash { get; set; }
}


public class CatalogAudioStreamEntry
{
    public int bitrate { get; set; }
    public string codec { get; set; }
    public string language { get; set; }
    public int channels { get; set; }
    public string features { get; set; }
}

这是一对多关系。我正在尝试从数据库中检索DbCatalogEntry个对象的列表,并在同一个查询中填充audiostreams

我尝试了以下但不起作用:

var MovieEntryList = 
    (from vwCat in ctx.sp_GetMovieCatalog(getCurrentUserId())
      select new DbCatalogEntry()
          {
              id = vwCat.id,
              size = vwCat.size,
              duration = vwCat.duration,
              vcodec = vwCat.codec,
              Filename = vwCat.filename,
              imdbId = vwCat.imdb_id,
              mxHash = vwCat.mxhash,
              ownedByUser = (int)vwCat.owned,
              width = vwCat.width,
              height =  vwCat.height,
              audiostreams = 
                (from astr in ctx.audiostreamentry
                  where astr.movie_id == vwCat.id
                  select new CatalogAudioStreamEntry()
                      {
                          bitrate = astr.bitrate,
                          channels = astr.channels,
                          codec = astr.codec,
                          features = astr.features,
                          language = astr.language
                      }).ToList()
          }).ToList();

搜索显示您无法将ToList()放入linq到实体查询,因为它无法转换转换。我读了很多关于将audiostreams更改为IEnumerable的建议,但也无法使其工作。大多数尝试都编译得很好,但在运行时使用无法创建类型的常量值...

有人能指出我解决这个问题的正确方向吗?重要的是,必须将到数据库的往返次数保持在最低限度,因此无法为每个DbCatalogEntry创建一个客户端子查询来填充列表。

更新#1:

提供更多详细信息:这是EF从我的数据库生成的模型: Model

sp_GetMovieCatalog(getCurrentUserId())是SQL服务器上的存储函数,它接受一个用于过滤结果的参数。

我想要做的是从movieenty中选择并加载audiostreamenty中的所有关联行。 此数据应用于创建DbCatalogEntry的实例,因此结果类型为List<DbCatalogEntry>

这有可能吗?也许有更好/更容易的解决方案?

1 个答案:

答案 0 :(得分:1)

我相信,你有问题,因为尝试为多个查询使用相同的上下文

你可以这样试试:

    var MovieEntryList = 
    (from vwCat in ctx.sp_MovieCatalog
    where vwCat.owned = currentUserId
    select new DbCatalogEntry()
      {
          id = vwCat.id,
          size = vwCat.size,
          duration = vwCat.duration,
          vcodec = vwCat.codec,
          Filename = vwCat.filename,
          imdbId = vwCat.imdb_id,
          mxHash = vwCat.mxhash,
          ownedByUser = (int)vwCat.owned,
          width = vwCat.width,
          height =  vwCat.height,
          audiostreams = vwCat.audiostreamentry.Select(astr=>
               new CatalogAudioStreamEntry()
                  {
                      bitrate = astr.bitrate,
                      channels = astr.channels,
                      codec = astr.codec,
                      features = astr.features,
                      language = astr.language
                  }).ToList()
      }).ToList();

或者这样:

    var MovieEntryList = ctx.audiostreamentry.where(p=>p.movieCatolog.ownedByUser - currentUserId)
    //.ToList() //if you call ToList() here futher will be LINQ to Object, and you want have most of problems
    .GroupBy(p=>new {Id = p.movieCatolog.id, Owner = p.movieCatolog.p.movieCatolog.id})
    .Select(p=> new DbCatalogEntry{
    id = p.Key.Id,
    ownedByUser = p.Key.Owner,
    audiostrams = p.Select(x=>new CatalogAudioStreamEntry
    {
                      bitrate = astr.bitrate,
                      channels = astr.channels,
                      codec = astr.codec,
                      features = astr.features,
                      language = astr.language
                  })

    })