我有以下课程:
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从我的数据库生成的模型:
sp_GetMovieCatalog(getCurrentUserId())
是SQL服务器上的存储函数,它接受一个用于过滤结果的参数。
我想要做的是从movieenty
中选择并加载audiostreamenty
中的所有关联行。
此数据应用于创建DbCatalogEntry
的实例,因此结果类型为List<DbCatalogEntry>
。
这有可能吗?也许有更好/更容易的解决方案?
答案 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
})
})