Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用子对象更新实体是否需要初始查询_C#_.net_Entity Framework_Entity Framework 6 - Fatal编程技术网

C# 使用子对象更新实体是否需要初始查询

C# 使用子对象更新实体是否需要初始查询,c#,.net,entity-framework,entity-framework-6,C#,.net,Entity Framework,Entity Framework 6,我有一个相册实体: public class Album { public Album() { } [Key] [Column("AlbumId")] public int Id { get; set; } public string Title { get; set; } public int ReleaseYear { get; set; } public int Rating { get; set; }

我有一个相册实体:

public class Album
{
    public Album() { }

    [Key]
    [Column("AlbumId")]
    public int Id { get; set; }
    public string Title { get; set; }        
    public int ReleaseYear { get; set; }
    public int Rating { get; set; }        
    public int ComposerId { get; set; }

    [ForeignKey("ComposerId")]
    public Composer Composer { get; set; }


}
其中包含作为子对象的Composer:

public class Composer
{
    [Key]
    [Column("ComposerId")]
    public int Id { get; set; }
    public string Name { get; set; }
}
在我的相册更新方法中,我有以下正确工作的代码:

public void UpdateAlbum(Album album)
{
    using (var context = new MusicCatelogContext())
    {
        try
        {
                Album albumEntity = context.Albums
                        .Where(a => a.Id.Equals(album.Id))
                        .Include(a => a.Composer)
                        .First();                        

                Composer composerEntity = context.Composers
                        .Where(c => c.Id.Equals(album.Composer.Id))
                        .First();

                context.Entry(albumEntity).CurrentValues.SetValues(album);
                albumEntity.Composer = composerEntity;


                context.SaveChanges();

        }
上述代码虽然有效,但需要对数据库进行两次查询。我希望能够按照以下方式连接更新的相册实体:

public void UpdateAlbum(Album album)
{
    using (var context = new MusicCatelogContext())
    {
        try
        {    
            context.Entry(album).State = EntityState.Modified;                
            context.SaveChanges();    
        }
但是,当我尝试此代码时,当我尝试设置状态时会引发以下异常:

发生引用完整性约束冲突:关系一端的'Composer.Id'属性值与另一端的'Album.ComposerId'属性值不匹配。

我做了很多研究,但我仍然不确定为什么会这样。我应该注意到,在
album
参数中传递给
UpdateAlbum
的整个Composer对象是新的更新版本

因此,我的问题是:

  • 第一个版本是否是使用子对象更新现有实体的唯一方法(即,需要初始选择)
  • 如果不是,导致错误的代码的第二个版本有什么问题

  • 谢谢。

    据我所知,这是EF的标准行为。我也相信这是正确的行为。当您点击DB时,可能发生了很多事情,另一个进程/用户删除了该对象或更改了该对象。您是开发人员,希望了解这一点。你也应该问问自己为什么要担心这个。只有当您进行大规模批量更新时,您才会受到性能损失,但此处不会。该错误也是标准错误,因为EF希望插入新对象,因此它不在其上下文中。上下文。条目(相册)。状态=EntityState.Modified;做两件事:将对象相册附加到上下文,并告诉EF此对象将按原样保存到数据库。但是,composer Id与与album相关的对象图中的composer Id不匹配(您刚刚将其设置为其他值)。将FK设置为“保存前一个”,不要公开FK属性(让EF处理它),或者像在第二个示例中那样将正确的编写器条目附加到上下文中。@Aldert EF不会插入新对象,因为.entry方法适用于ChangeTracker(没有导航属性,因此不考虑引用的条目)…另一方面,Set.Add Previous确实会尝试插入相关条目,并可能引发不同的错误。@Devil,据我所知,这只是上下文对象范围内的情况。通常您实例化上下文,运行业务逻辑并处理上下文。您是对的,在这个上下文中,我们需要一个ChangeTracker在上面的示例中,刚刚创建了上下文,因此changetracker为空。