【问题标题】:Relationships in Entity Framework Code First实体框架代码优先中的关系
【发布时间】:2013-11-25 20:25:03
【问题描述】:

昨天我在 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 约束。 无法创建约束。见以前的错误。或其主人未找到或没有视图引擎支持搜索的位置。

我不知道如何解决。

【问题讨论】:

    标签: c# entity-framework foreign-keys code-first


    【解决方案1】:

    InversePropertyAttribute 指定该关系应使用哪个导航属性

    导航属性必须是实体类型(例如在模型中声明的类型,GameModel)或实现ICollection&lt;T&gt; 的某种类型,其中T 必须是实体类型。 UserModel.Idint,显然不满足该条件。

    因此,如果您将类型更改为 ICollection&lt;GameModel&gt;GameModel.Creator 的逆属性可能是 UserModel.Games,或者必须保持未指定。如果您不指定逆属性,EF 将尝试自行解决所有问题(在这种情况下,它会正确地将 GameModel.Creator 识别为导航属性,但 UserModel.Games 很可能会抛出异常,因为它是既不是实体类型,也不是以T 为实体类型实现ICollection&lt;T&gt;,从数据库的角度来看,它也不是原始类型)。但是,EF 的 work-everything-out-by-itself-magic 并不能很好地处理相同实体类型之间的多个关系,这就是需要 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 知道它必须生成 2 个从 SomePrettyImportantStuffOtherImportantStuff 的 FK,名称为 Id1Id2,但它无法判断哪个 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);
    }
    

    【讨论】:

    • 感谢您的回复。我编辑了我的帖子,因为我有另一个问题。请看一下
    猜你喜欢
    • 2012-03-31
    • 2012-10-11
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    相关资源
    最近更新 更多