Let me first give some background: I'm creating an application, which should handle a DB. That DB might evolve (extra tables/columns/constraints might be added, but nothing gets removed, in fact the DB gets more and more elaborated).
I started with a "Database First" approach and as a result, I have created an Entity Framework diagram, with according classes in *.cs
files. Two of those files are (only some interesting fields):
Area.cs:
public partial class Area
{
public Area() { }
public string Name { get; set; }
public int Id { get; set; }
}
Location.cs:
public partial class Location
{
public Location() { }
public string Name { get; set; }
public int Id { get; set; }
...
public Nullable<int> AreaId { get; set; }
}
This is generated from a version of the DB, which does not cover constraints, and now I would like to add a ForeignKeyConstraint
to the corresponding Entity Framework model:
Location.AreaId
is a foreign key towardsArea.Id
- There are many
Location
objects for oneArea
object - It's the idea to prevent deletion of
Area
objects, being referred to byLocation
objects).
I believe this should be done as follows:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Area>().HasKey(t => t.Id); // Creation of primary key
modelBuilder.Entity<Location>().HasKey(t => t.Id); // Creation of primary key
modelBuilder.Entity<Location>().HasRequired(n => n.AreaId)
.WithMany(...)
.HasForeignKey(n => n.AreaId);
...
This, obviously, does not work. I'm missing following information:
- My "Area.cs" file does not contain a reference to the
Location
object (as this version of the DB does not contain constraints, this has not been added by the "database first" wizard), should I add this or can I solve my issue without? - What do I need to fill in instead of the ellipsis
.WithMany(...)
? - Extra question: I'm aware of the
ForeignKey
directive. Should I replacepublic Nullable<int> AreaId { get; set; }
in "Location.cs" by[ForeignKey("AreaId")]
, followed bypublic virtual Area Area { get; set; }
?
Edit
Important remark: as "Location.cs" and "Area.cs" are auto-generated, I like to minimise changes in those files.
Next edit
Meanwhile I've updated my "Location.cs" file as follows:
...
// public Nullable<int> AreaId { get; set; }
[ForeignKey("AreaId")]
public Area Area { get; set;}
....
My OnModelCreating()
has been changed into:
modelBuilder.Entity<Location>().HasRequired(n => n.Area)
.WithMany(...)
.HasForeignKey(n => n.Area);
That leaves only the ellipsis problem to be solved.
Another edit
Since it takes such a long time for an answer (even for a comment), I've decided to add following line of source code to my "Area.cs" file:
public virtual ICollection<Location> Locations { get; set; }
I've then filled in the ellipsis as follows:
modelBuilder.Entity<Location>().HasRequired(l => l.Area)
.WithMany(a => a.Locations)
.HasForeignKey(l => l.Area);
Now just one question: how can I mention that the link between the Area
and the Location
should be handled by Location.AreaId
and Area.Id
(I know that Location.AreaId
is the foreign key, but how can I know that it refers to Area.Id
)?
Thanks in advance
CodePudding user response:
The simple answer to your last question. EF is recognizing that Area.Id
is a primary key so connects Location.AreaId
to Area.Id
Also, here is a simple guide on how to do it.