通过构造函数分配作为外键的对象会修改主键

时间:2014-11-18 10:08:56

标签: sqlite entity-framework-core

我有两个课程:PatientCountryPatient包含CountryOfOrigin类型的属性Country。我已经建立了这样的关系:

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<Patient>().OneToOne<Country>(x => x.CountryOfOrigin);
        }

(一名患者出生在一个国家)

每当我构建一个新的Patient时,我希望将其分配为Country作为CountryOfOrigin。

var country = (from c in db.Countries
               where c.Code.Equals(countryCode,
                   StringComparison.InvariantCultureIgnoreCase)
               select c).First();

>> db.Patients.Add(new Patient(firstName, lastName, birthDate, country));
db.SaveChanges();

但是,我在标有&#39;&gt;&gt;&#39;

的行上收到以下例外情况
  

base {&#34; The property&#39; CountryId&#39;在实体类型上   &#39; SqlLitePlayground.DataAccess.Country&#39;是只读的,所以不可能   修改或标记为已修改。&#34;} System.SystemException   {System.NotSupportedException}

调试时我注意到以下内容:抛出异常CountryId的行(具有私有setter的属性,按约定检测为主键)是1之前。抛出异常后,CountryId-1。在我的代码中没有任何地方我改变CountryId的值(由于私有的setter也是不可能的)所以我假设这发生在DbSet方法db.Patients.Add(...)但是我不明白为什么或者我如何纠正这种行为。

我的最终问题是,(如何)我可以使用具体对象而不是整数的外键?

请注意,这是一个玩具项目,开始学习EF7,我关心数据库中当前的数据,我只是想学习如何为某些场景建模。

1 个答案:

答案 0 :(得分:0)

最终问题不在我预期的地方。我定义了private无参数构造函数而不是protected无参数构造函数。没有MSDN样本(在EF6上)提到这一点,因为他们的类没有构造函数(可能是为了保持代码简短)。

这禁止实体框架生成代理类。这样做的一些副作用显然是将Id设置为-1。或许这就是框架试图警告我的方式(下次请抛出异常;))。

一个很好的参考资料,解释代理类及其生成所需的规则:

http://msdn.microsoft.com/en-us/library/vstudio/dd468057(v=vs.100).aspx