昨天我在Management Studio中创建了数据库,现在我想使用EF Code First在程序中创建它。
以下是我的数据库的链接:http://s11.postimg.org/6sv6cucgj/1462037_646961388683482_1557326399_n.jpg
我做了什么:
public class GameModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreationTime { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string TotalTime { get; set; }
public DateTime RouteStartTime { get; set; }
public DateTime RouteEndTime { get; set; }
public int MaxPlayersPerTeam { get; set; }
public int CityId { get; set; }
public int CreatorId { get; set; }
[InverseProperty("Id")]
[ForeignKey("CreatorId")]
//public int TeamId { get; set; }
//[ForeignKey("TeamId")]
public virtual UserModel Creator { get; set; }
public virtual CityModel City { get; set; }
//public virtual TeamModel WinnerTeam { get; set; }
}
public class RegionModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<CityModel> Cities { get; set; }
}
public class CityModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int RegionId { get; set; }
public virtual RegionModel Region { get; set; }
public virtual ICollection<UserModel> Users { get; set; }
public virtual ICollection<GameModel> Games { get; set; }
}
public class UserModel
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public DateTime RegistrationDate { get; set; }
public string FacebookId { get; set; }
public int CityId { get; set; }
public virtual CityModel City { get; set; }
public virtual IEnumerable<GameModel> Games { get; set; }
}
现在我想创建4个表但是我有一些问题...我想在GameModel中创建CreatorId,但是它不起作用...当我写UserId而不是CreatorId时它正在工作(没有[InverseProperty] (“Id”)]和[ForeignKey(“CreatorId”)])。
这就是我得到的:
视图'属性'Id'无法配置为导航属性。该属性必须是有效的实体类型,并且该属性应具有非抽象的getter和setter。对于集合属性,类型必须实现ICollection,其中T是有效的实体类型。或者找不到它的主人,或者没有视图引擎支持搜索到的位置。
编辑: 我这样改了:
public int CityId { get; set; }
public int CreatorId { get; set; }
[ForeignKey("CityId")]
public virtual CityModel City { get; set; }
[ForeignKey("CreatorId")]
public virtual UserModel Creator { get; set; }
还有另一个问题。
视图'在'UserModels'表上引入FOREIGN KEY约束'FK_dbo.UserModels_dbo.CityModels_CityId'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 无法创建约束。看看以前的错误。'或者找不到它的主人,或者没有视图引擎支持搜索到的位置。
我不知道如何解决它。
答案 0 :(得分:9)
InversePropertyAttribute
指定哪个导航属性应该用于该关系。
导航属性必须是实体类型(模型中声明的类型,例如GameModel
)或实现ICollection<T>
的某种类型,其中T
必须是实体类型。 UserModel.Id
是int
,显然不满足该条件。
因此,如果您将类型更改为GameModel.Creator
,或者必须保持未指定,则UserModel.Games
的反向属性可以是ICollection<GameModel>
。如果你没有指定反向属性,EF将尝试自己完成所有工作(在这种情况下,它会正确识别GameModel.Creator
作为导航属性,但UserModel.Games
很可能会抛出异常,因为它既不是实体类型,也不实现ICollection<T>
T
是实体类型,从数据库的角度来看也不是原始类型)。然而,EF的工作 - 一切都是自己 - 魔术并不能很好地应对相同实体类型之间的多重关系,即需要InversePropertyAttribute
时。
一个展示问题的简单示例:
class SomePrettyImportantStuff {
[Key]
public int ID { get; set; }
public int OtherId1 { get; set; }
public int OtherId2 { get; set; }
[ForeignKey("OtherId1")]
public virtual OtherImportantStuff Nav1 { get; set; }
[ForeignKey("OtherId2")]
public virtual OtherImportantStuff Nav2 { get; set; }
}
class OtherImportantStuff {
[Key]
public int ID { get; set; }
public virtual ICollection<SomePrettyImportantStuff> SoldStuff { get; set; }
public virtual ICollection<SomePrettyImportantStuff> BoughtStuff { get; set; }
}
在这里,EF知道它必须从SomePrettyImportantStuff
到OtherImportantStuff
生成名称为Id1
和Id2
的2个FK,但它无法分辨出哪个ID指的是从中出售的实体,以及从中购买的实体。
编辑:如何解决循环参考问题
要修复该问题,您的上下文类应覆盖OnModelCreating
并配置不应相应删除的外键,如下所示:
protected override void OnModelCreating(DbModelBuilder builder)
{
builder.Entity<CityModel>().HasMany(c => c.Users).WithRequired(u => u.City)
.HasForeignKey(u => u.CityId).WillCascadeOnDelete(value: false);
// Add other non-cascading FK declarations here
base.OnModelCreating(builder);
}