c# - Entity Framework Code First 中的关系

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

昨天我在 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")]).

这是我得到的:

The view 'The property 'Id' cannot be configured as a navigation property. The property must be a valid entity type and the property should have a non-abstract getter and setter. For collection properties the type must implement ICollection where T is a valid entity type.' or its master was not found or no view engine supports the searched locations.

编辑: 我是这样改的:

    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; }

还有一个问题。

The view 'Introducing FOREIGN KEY constraint 'FK_dbo.UserModels_dbo.CityModels_CityId' on table 'UserModels' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint. See previous errors.' or its master was not found or no view engine supports the searched locations.

我不知道怎么解决。

最佳答案

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 生成 2 个 FK至 OtherImportantStuff名字是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);
}

关于c# - Entity Framework Code First 中的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20202578/

相关文章:

c# - AES _Encryption 在 Mysql 中,在 C#.Net 中解密

c# - 如何将 Char 转换为 .Net 中的 Keycode?

c# - 在内存中编辑 ZipArchive .NET

entity-framework - 单个查询中的EF多个聚合

c# - foreach 循环中的 DeleteObject()

c# - TryParse困境-处理out参数

c# - 如何获取 Entity Framework 来更新复杂类型?

mysql - 为已经在使用中的主键创建外键

mysql - 无法添加我的第二个外键约束

mysql - 查找外键约束失败的行