我有几节课,
public class Album
{
public int AlbumId { get; set; }
public string Title { get; set; }
public Genre genre { get; set; }
public virtual Artist artist { get; set; }
}
public class Artist
{
public int ArtistId { get; set; }
public string Name { get; set; }
public virtual ICollection<Album> albums { get; set; }
}
public class ArtistResponse
{
public int ArtistId { get; set; }
public string Name { get; set; }
}
public class AlbumResponse
{
public int AlbumId { get; set; }
public string Title { get; set; }
public Genre genre { get; set; }
public ArtistResponse artist { get; set; }
}
我尝试使用艺术家下载所有专辑,然后使用AlbumResponse返回。 我有一个LINQ表达式
return ctx.Albums.Include(i => i.artist).Select(i => new AlbumResponse
{
AlbumId = i.AlbumId,
artist = new ArtistResponse { Name=i.artist.Name, ArtistId=i.artist.ArtistId},
genre = i.genre,
Title = i.Title
}).ToList();
所以我包括&#39;艺术家&#39; by&#34; Include()&#34;然后创建新的AlbumResponse,我在其中创建新的ArtistResponse。不幸的是,它不起作用。它会抛出InvalidOperationException。 &#34; i.artist.ArtistId&#34;是一个null,我不知道为什么,没有ArtistId初始化工作一切正常,只有&#34; Name = i.artist.Name&#34;工作得很好。
如何将ArtistId附加到&#39;艺术家&#39;在&#39; AlbumResponse&#39;? 例外:&#34;演员价值类型&#39; System.Int32&#39;失败,因为具体化值为null。结果类型的通用参数或查询必须使用可空类型&#34; 课程相册和艺术家在数据库中,AlbumId和ArtistId不可为空。 ArtistResponse和AlbumResponse只是&#34;额外&#34;用于在数据库中添加或获取信息的类,所以ArtistId和AlbumId在&#34; * Response&#34;只是整理
答案 0 :(得分:2)
如果ArtistId
导航属性的artist
列为Nullable<int>
且ArtistId
类型的ArtistResponse
属性类型为{{1你应该检查是否有值返回:
int
这显然只是一个猜测,因为你没有发布你的类型的定义,也没有发现你得到的实际错误信息。
修改强>
如果您将return ctx.Albums.Include(i => i.artist).Select(i => new AlbumResponse
{
AlbumId = i.AlbumId,
artist = new ArtistResponse { Name = (i.artist != null) ? i.artist.Name : string.Empty, ArtistId = (i.artist != null && i.artist.ArtistId.HasValue) ? artist.ArtistId.Value : 0 },
genre = i.genre,
Title = i.Title
}).ToList();
类型的ArtistId
属性类型更改为ArtistResponse
(Nullable<int>
),该怎么办:
int?
答案 1 :(得分:1)
return ctx.Albums.Include(i => i.artist).Select(i => new AlbumResponse
{
AlbumId = i.AlbumId,
artist = new ArtistResponse { Name=i.artist.Name, ArtistId=i.artist.ArtistId ?? 0( or Guid.NewGuid() << or this if you decide to use guid type)},
genre = i.genre,
Title = i.Title
}).ToList();
如果您不想将其默认为零,则必须为您的艺术家ID指定唯一的数字/键。也许是新的guid?你必须找到一种方法来创建一个独特的int id。
答案 2 :(得分:1)
你可能,我不是说你没有完全的知识,做一个不完整的投射。实体对数据有点奇怪,因为它是一个官方对象,它不会被实现用于门外。 EG:您的位置,选择和其他扩展语法不起作用,因为该对象尚未实现。
您可能希望尝试一些简单的事情:
return ctx.Albums.Include(i => i.artist)
<强> .ToList()强>
.Select(i => new AlbumResponse
{
AlbumId = i.AlbumId,
artist = new ArtistResponse { Name= i?.artist?.Name ?? String.Empty, ArtistId=i?.artist?.ArtistId ?? 0},
genre = i.genre,
Title = i.Title
}).ToList();
否则投影可能无法实现其导航属性“艺术家”。 ToList()是穷人快速实现投射的方式,并且基本上说:“.NET现在可以作为合法的对象集合”。您可以使用我认为的“其他扩展”,我相信也是如此。这只是一个猜测,但我知道我已经与EF合作了一段时间,并且在进行加载事件,数学和其他事情时“实现”通常是罪魁祸首。或者它可能正如其他人所说的那样,你只是获得了导航的空引用,它就会爆炸。我做了一些伪代码?条件运算符(如果父元素也是空的话,基本上通过链检查空值而不是吹动)然后是一个合并的空运算符'??'如果这个东西为空,则指定一个默认值。