Relationships in Entity Framework Code First

c# code-first entity-framework foreign-keys

Question

I created a database in Management Studio yesterday, and today I want to use EF Code First to construct it in an application.

My database can be accessed here: http://s11.postimg.org/6sv6cucgj/1462037_646961388683482_1557326399_n.jpg

What I did was

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

I currently wanted to make 4 tables, however there are several issues. My attempt to create a CreatorId in the GameModel fails. Without [InverseProperty("Id")] and [ForeignKey("CreatorId")] it worked when I wrote UserId instead of CreatorId.

What I get is this:

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 made the following change:

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

There is still a problem.

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 don't know how to fix it.

1
4
11/25/2013 10:35:10 PM

Accepted Answer

The InversePropertyAttribute which navigational features should be used for that relation is specified.

An entity type (the types declared in your model, for example) must have a navigation property.GameModel (For instance) or a sort of implementationICollection<T> , whereT a type of entity is required.UserModel.Id is anint it obviously does not meet that need.

The opposite property ofGameModel.Creator might beUserModel.Games If the type was changed toICollection<GameModel> They had to go without being mentioned. EF will attempt to figure things out on its own if you don't specify an inverse property (in this case, it would correctly detectGameModel.Creator however, as a navigational propertyUserModel.Games would probably raise an exception because it neither implements nor corresponds to an entity type.ICollection<T> with T being an entity type, nor is it, in terms of databases, a primitive type). However, many relations between the same entity types are difficult for EF's work-everything-out-by-itself magic to handle.InversePropertyAttribute is required.

Here is a little illustration of the issue:

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

Here, EF is aware that it must produce 2 FKs fromSomePrettyImportantStuff to OtherImportantStuff adding the namesId1 and Id2 , but it is unable to distinguish between the IDs that identify the entity from whom it was purchased and the one from which it was sold.

How to address the cyclic reference issue

Your context class should override it to resolve the issue.OnModelCreating and appropriately configure the foreign keys that shouldn't cascade on deletion:

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);
}
9
11/27/2013 12:17:41 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow