Entity framework 实体框架-虚拟财产正在各自的表中插入数据

Entity framework 实体框架-虚拟财产正在各自的表中插入数据,entity-framework,Entity Framework,无论如何,我不确定问题的标题!我有一个模型类RandomStuff,它将环境作为虚拟财产 public class RandomStuff { //NOT SHOWN ON FORM HIDDEN JUST TO MAKE IT EASIER IN DB [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Newtonsoft.Json.JsonProperty]

无论如何,我不确定问题的标题!我有一个模型类
RandomStuff
,它将
环境
作为虚拟财产

public class RandomStuff
    {
        //NOT SHOWN ON FORM HIDDEN JUST TO MAKE IT EASIER IN DB
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Newtonsoft.Json.JsonProperty]
        public int JobId { get; set; }

        [Required]
        [ForeignKey("Environment")]
        [Newtonsoft.Json.JsonProperty]
        [DataMember(IsRequired = true)]
        public int EnvironmentId { get; set; }

        [Newtonsoft.Json.JsonProperty ]
        public virtual Environment Environment { get; set; }
}
我的环境如下:-

[Newtonsoft.Json.JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)]
    [DataContract]
    public class Environment
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Newtonsoft.Json.JsonProperty]
        public int Id { get; set; }

        [Required]
        [Newtonsoft.Json.JsonProperty]
        [DataMember(IsRequired = true)]
        public string Name { get; set; }

    }
现在,在我的控制器中,我有:-

public HttpResponseMessage Save(RandomStuff stuff)
        {
            if (ModelState.IsValid)
            {
                //Some stuff here
                db.RandomStuffs.Add(stuff);//When this excutes, it is 
                                           //inserting data in Environment table also.
                db.SaveChanges();


            }
        }
现在,每当我向我的
RandomStuff
表添加内容时,它也在添加环境

编辑:

我将试着用一般的例子来解释,这是我从


您的问题仍然不太清楚,因为您现在提供了另一篇文章中的代码片段,这些代码片段的结构甚至与您遇到问题的代码不同。然而,我仍然猜测您的问题在于重复插入,因此我将尝试提供一个建议

在实体框架数据库上下文上使用
Add()
方法时,它会将连接对象的整个图形标记为已添加的,即使该项已存在于数据库中。您可能看到的一种常见情况是,当您添加类型为
RandomStuff
的对象时,它也会添加类型为
Environment
的新对象,尽管
Environment.Name
是相同的,
Environment.Id
是数据库分配的,并且由于Entity Framework已将整个图形标记为添加的,它创建了一个新的环境对象,具有相同的
名称
,但有一个新的
Id
。因此,表中有多个
环境
行具有相同的
名称

解决方案看似简单。由于您的
RandomStuff
对象上已经有了一个属性来保存表示
Environment
对象的外键,因此无需向图形中添加新的
Environment
对象,只需创建
RandomStuff
对象并添加
EnvironmentId
的值即可。换句话说,

以下方式不是创建新的
RandomStuff
对象:

var RandomStuff randomStuff = new RandomStuff {
                                     Environment = new Environment {
                                                    Name = "Existing Environment"
                                                     }
                                     }
这样创建它:

var RandomStuff randomStuff = new RandomStuff {
                                     EnvironmentId = existingEnvironment.Id
                                    }

您的问题仍然不太清楚,因为您现在提供了另一篇文章中的代码片段,这些代码片段的结构甚至与您遇到问题的代码不同。然而,我仍然猜测您的问题在于重复插入,因此我将尝试提供一个建议

在实体框架数据库上下文上使用
Add()
方法时,它会将连接对象的整个图形标记为已添加的,即使该项已存在于数据库中。您可能看到的一种常见情况是,当您添加类型为
RandomStuff
的对象时,它也会添加类型为
Environment
的新对象,尽管
Environment.Name
是相同的,
Environment.Id
是数据库分配的,并且由于Entity Framework已将整个图形标记为添加的,它创建了一个新的环境对象,具有相同的
名称
,但有一个新的
Id
。因此,表中有多个
环境
行具有相同的
名称

解决方案看似简单。由于您的
RandomStuff
对象上已经有了一个属性来保存表示
Environment
对象的外键,因此无需向图形中添加新的
Environment
对象,只需创建
RandomStuff
对象并添加
EnvironmentId
的值即可。换句话说,

以下方式不是创建新的
RandomStuff
对象:

var RandomStuff randomStuff = new RandomStuff {
                                     Environment = new Environment {
                                                    Name = "Existing Environment"
                                                     }
                                     }
这样创建它:

var RandomStuff randomStuff = new RandomStuff {
                                     EnvironmentId = existingEnvironment.Id
                                    }

请你回复一下反对票的原因,好吗(你的问题是否与实体框架创建相关实体的重复插入有关?@AndrewCounts-在你发表评论后,我只是在谷歌上搜索了你所说的“实体框架创建相关实体的重复插入”,我找到了一种更简单的方法来解释我的问题。请查看我问题的编辑。谢谢!请你回复一下反对票的理由好吗(你的问题是否与实体框架创建相关实体的重复插入有关?@AndrewCounts-在你发表评论后,我只是在谷歌上搜索了你所说的“实体框架创建相关实体的重复插入”,我找到了一种更简单的方法来解释我的问题。请查看我问题的编辑。谢谢
var RandomStuff randomStuff = new RandomStuff {
                                     EnvironmentId = existingEnvironment.Id
                                    }