我在实体框架中遇到问题。
我有以下课程(简化):
public class Building
{
public int ID { get; set; }
// *.. snip..* other properties
public Location Location { get; private set; }
}
public class Location
{
public string Street {get; set;}
public Country country {get; set}
}
public class Country
{
public int ID { get; set; }
public string Name { get; set; }
}
建筑物和国家/地区是实体,它们保存在数据库中。位置是值类型,应该映射到与Building相同的表。
但是,当我以这种方式映射它时,实体框架也希望将Location映射到一个表,并抱怨它没有Key。我不想给它一把钥匙,因为它属于建筑物,根本不应该是一个实体。
我见过一些解决方法,说你需要将Country放在Building-class上,但这感觉不好(并且在语义上是完全错误的)。
我正在使用Entity Framework 5
答案 0 :(得分:1)
自Entity Framework Core 2发布以来,现在可以使用owned entities实现这一目标。
您的配置如下:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// ...
modelBuilder.Entity<Building>().OwnsOne(x => x.Location);
modelBuilder.Entity<Location>().HasOne(x => x.Country);
// ...
}
这样,Location
类中的属性将成为表Building
类所映射的一部分。这意味着您将仅具有Building
和Country
类的表,并且Building
表将具有Country
表的外键。
我知道您发布问题已经很久了,但是我认为此答案可能会对遇到此问题的人有所帮助。
答案 1 :(得分:0)
在我看来,实体框架不应该允许这样的情况。
我知道您不会将位置视为实体,但添加实体对复杂类型的引用似乎也不是一个可靠的方法。建筑物与国家的关系非常直接。建筑物属于一个国家。因此,建筑模型应包括国家ID。你期望映射什么?
如果您希望表格Building只有三列ID, Street, CountryId
而您仍想保留位置模型,则应使用以下复杂类型。
public class Location
{
public string Street {get; set;}
public int countryId {get; set}
}
但是,如果您希望您的Building表格包含模型Country中的所有字段,那么可能会导致一些棘手的情况,例如您希望向Country模型添加新字段或者如果您想添加其他字段根据新业务案例,您的国家/地区模型的复杂类型或实体。
这些案例会混淆关系概念,并且会在没有任何有意义的理由的情况下使您的结构过于复杂。 (当然我认为)
答案 2 :(得分:-3)
您可以使用[NotMapped]属性在Building类中标记Location属性。
using System.ComponentModel.DataAnnotations.Schema;
public class Building
{
[NotMapped]
public Location Location { get; private set; }
}
希望能解决你的问题!