在实体框架代码优先关系 [英] Relationships in Entity Framework Code First

查看:211
本文介绍了在实体框架代码优先关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

昨天我Management Studio中创建的数据库,现在我想用EF代码优先程序来创建它

yesterday I created database in Management Studio and now I want to create it in program using EF Code First.

这是链接到我的数据库:的 http://s11.postimg.org/6sv6cucgj/1462037_646961388683482_1557326399_n.jpg

Here is link to my database: 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个表,但我有一些问题..我想打的CreatorID在GameModel,但它不工作...当我写的用户ID,而不是它的creatorID是工作(不包括[InverseProperty(ID)]和[ForeignKey的(的CreatorID)])。

For now I wanted to create 4 tables but I have some problems... I want to make CreatorId in GameModel, but it doesn't work... When i wrote UserId instead of CreatorId it was working ( without [InverseProperty("Id")] and [ForeignKey("CreatorId")]).

这是我所得到的:

视图'属性'ID'不能被配置为导航属性。该物业必须是有效的实体类型和属性应该有一个非抽象的getter和setter。对于集合属性的类型必须实现ICollection的,其中T是一个有效的实体类型。'或它的主人没有被发现或没有视图引擎支持搜索到的位置。

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.

编辑:
我改变了它是这样的:

edit: I changed it like this:

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

和还有另一个问题。

视图对表''引进国外KEY约束'FK_dbo.UserModels_dbo.CityModels_CityId UserModels'可能会导致循环或多重级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。
无法创建约束。请参阅以前的错误。或它的主人没有被发现或没有视图引擎支持搜索到的位置。

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.

和我不知道如何解决这个问题。

And I have no idea how to solve it.

推荐答案

InversePropertyAttribute 指定,其中的导航属性的应该用于这种关系。

The InversePropertyAttribute specifies, which navigation property should be used for that relation.

一个导航属性​​必须是实体类型(在模型中声明的类型, GameModel )后,或某些类型的实施的ICollection< T> ,其中 T 有是一个实体类型。 UserModel.Id INT ,这显然不符合这一条件。

A navigation property must be of an entity type (the types declared in your model, GameModel for example) or some type implementing ICollection<T>, where T has to be an entity type. UserModel.Id is an int, which clearly doesn't satisfy that condition.

所以,逆财产 GameModel.Creator 可能是 UserModel.Games 如果你改变类型为的ICollection< GameModel> ,或不得不不指定。如果不指定inverse属性,EF会尝试一切制定出自己的(在这种情况下,将正确识别 GameModel.Creator 作为导航属性,但 UserModel.Games 最有可能抛出一个异常,因为这既不是实体类型,也不实施的ICollection< T> T 作为一个实体类型,也不是从一个数据库点基本类型)。然而,英孚的工作都出按自身魔法不相同的实体类型之间的多重关系处理得很好,需要 InversePropertyAttribute 时,这是。

So, the inverse property of GameModel.Creator could be UserModel.Games if you changed the type to ICollection<GameModel>, or had to be left unspecified. If you don't specify an inverse property, EF will try to work everything out on its own (in this case it would properly recognize GameModel.Creator as a navigation property, but UserModel.Games would most likely throw an exception, as it is neither an entity type, nor does it implement ICollection<T> with T being an entity type, nor is it a primitive type from a database point of view). However, EF's work-everything-out-by-itself-magic doesn't cope too well with multiple relations between the same entity types, which is when the InversePropertyAttribute is needed.

一个简单的例子演示该问题:

A quick example that demonstrates the problem:

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知道它来生成<$ C 2 FKS $ C> SomePrettyImportantStuff 到 OtherImportantStuff 的名称为Id1 ID2 ,但是却没有办法告诉它的ID是指它是从销售,这是一个它是从买的实体。

Here, EF knows that it has to generate 2 FKs from SomePrettyImportantStuff to OtherImportantStuff with the names Id1 and Id2, but it has no way to tell which of the IDs refers to the entity where it was sold from and which is the one it was bought from.

编辑:如何解决循环引用问题

要解决这个问题,你的上下文类应重写 OnModelCreating 和配置,不应该对级联删除相应的,像这样的外键:

To fix that problem, your context class should override OnModelCreating and configure the foreign keys which shouldn't cascade on delete accordingly, like this:

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

这篇关于在实体框架代码优先关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆