I've got a simple question regarding foreign keys and mapping in Entity Framework. For example, I have a class RestaurantGuest:
public interface IUser
{
int Id { get; set; }
}
public class RestaurantGuest : IUser
{
public int Id { get; set; }
}
And class Visit in another assembly, that should have reference to the RestaurantGuest by foreign key:
public class Visit
{
public int Id { get; set; }
public IUser Guest { get; set; }
public int GuestId { get; set; }
}
The RestaurantGuestclass does not and should not have an IList<Visit> Visits {get;set;}
How to map it in Entity Framework?
I expected something like this (but it does not work):
builder.VersionedEntity<Visit>().ToTable("Visits")
.WithRequired(v => v.Guest).ToTable("RestaurantGuests")
.HasForeignKey(o => o.GuestId)
but all tutorials will suggest to do this:
builder.VersionedEntity<RestaurantGuest>()
.HasMany(o => o.Visits)
.WithRequired(v => v.Guest)
.HasForeignKey(v => v.GuestId);
I don't want to add a list of Visits to the RestaurantGuest. RestaurantGuest should not know anything about the visits.
Since your Guest
is actually an Interface, I guess you can't map it directly, because first of all you can't even assume it'll be always a RestaurantGuest.
I like using a factory like this:
public interface IUser
{
int Id { get; set; }
}
public class RestaurantGuest : IUser
{
public int Id { get; set; }
}
public class Visit
{
public int Id { get; set; }
public virtual GuestFactory Guest { get; set; }
public int GuestId { get; set; }
}
public class GuestFactory: IUser
{
public int Id { get; set; }
public IUser Build()
{
return new RestaurantGuest { Id = this.Id };
}
}
builder.VersionedEntity().HasMany()
.WithRequired(v => v.Restaurant).HasForeignKey(v => v.RestaurantId);
Inside the build
method, you apply whatever logic you need to instantiate the proper concrete class, in your case a RestaurantGuest
. You configure it like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<GuestFactory>().ToTable("RestaurantGuest");
modelBuilder.Entity<Visit>()
.HasRequired(v => v.Guest)
.WithMany()
.HasForeignKey(v => v.GuestId);
}
And when you ran a migration of this, this is the output:
public partial class RestaurantTest : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.RestaurantGuest",
c => new
{
Id = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Visits",
c => new
{
Id = c.Int(nullable: false, identity: true),
GuestId = c.Int(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.RestaurantGuest", t => t.GuestId, cascadeDelete: true)
.Index(t => t.GuestId);
}
public override void Down()
{
DropForeignKey("dbo.Visits", "GuestId", "dbo.RestaurantGuest");
DropIndex("dbo.Visits", new[] { "GuestId" });
DropTable("dbo.Visits");
DropTable("dbo.RestaurantGuest");
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.