0

我有两个班级: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();

但是,在标有“>>”的行上出现以下异常

base {“实体类型'SqlLitePlayground.DataAccess.Country'上的属性'CountryId'是只读的,因此不能修改或标记为已修改。”} System.SystemException {System.NotSupportedException}

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

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

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

4

1 回答 1

0

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

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

一个很好的参考,解释了代理类以及生成它们需要哪些规则:

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

于 2014-11-19T10:32:47.863 回答