[英]EF Code First Foreign Key Relationship
I have the the following situation: 我有以下情况:
My model classes look like this: 我的模型类如下所示:
public class GameTable
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id
{
get;
set;
}
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
public Guid CreatorId { get; set; }
[ForeignKey(nameof(CreatorId))]
public Account Creator { get; set; }
}
public class Account
{
public Account()
{
Elo = 1000;
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
[MaxLength(15)]
[MinLength(4)]
public string Name { get; set; }
[Required]
[MaxLength(32)]
[MinLength(32)]
public string PasswordHash { get; set; }
public int Elo { get; set; }
public bool IsAdmin { get; set; }
public Guid? CurrentTableId { get; set; }
[ForeignKey(nameof(CurrentTableId))]
public virtual GameTable CurrentTable { get; set; }
}
My context is currently looking like this: 我的上下文当前看起来像这样:
[Export(typeof(MyDbContext)), PartCreationPolicy(CreationPolicy.Shared)]
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class MyDbContext : DbContext
{
public MyDbContext() : base("DbContextCon")
{
Database.SetInitializer<PiksenDbContext>(new CreateDatabaseIfNotExists<PiksenDbContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
public virtual DbSet<Account> Accounts { get; set; }
public virtual DbSet<SecurityToken> SecurityTokens { get; set; }
public virtual DbSet<GameTable> GameTables { get; set; }
}
Unfortunately it doesn't work with both foreign key set up like this. 不幸的是,这不适用于像这样设置的两个外键。 The following message is giving my some headache at the moment: 以下消息目前让我有些头疼:
System.InvalidOperationException: 'Unable to determine the principal end of an association between the types 'namespace.GameTable' and 'namespace.Account'. System.InvalidOperationException:'无法确定类型'namespace.GameTable'和'namespace.Account'之间的关联的主要终点。 The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.' 必须使用关系流利的API或数据注释显式配置此关联的主要端。
However, when I comment out one of the FK-Relationships, everything is fine. 但是,当我注释掉FK关系之一时,一切都很好。 It seems like there is some sort of conflict between those two. 似乎这两者之间存在某种冲突。
The result I am trying to get is one nullable FK in Account
called CurrentTableId
and a non-nullable FK in GameTable
called CreatorId
. 我想获得的结果是一个可空FK在Account
名为CurrentTableId
和非空的FK GameTable
所谓CreatorId
。
On each side of the FK relationship you can (should normally) have Navigation Properties. 在FK关系的每一侧,您都可以(通常应该)具有导航属性。 And when there are multiple FK relationships, you can use the InversePropertyAttribute to specify which FK a pair of Navigation Properties represents. 并且当存在多个FK关系时,可以使用InversePropertyAttribute指定一对导航属性代表哪个FK。
EG 例如
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ef62test
{
class Program
{
public class GameTable
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id
{
get;
set;
}
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
public Guid CreatorId { get; set; }
[ForeignKey(nameof(CreatorId))]
public Account Creator { get; set; }
[InverseProperty(nameof(Account.CurrentTable))]
public ICollection<Account> CurrentPlayers { get; } = new HashSet<Account>();
}
public class Account
{
public Account()
{
Elo = 1000;
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
[MaxLength(15)]
[MinLength(4)]
public string Name { get; set; }
[Required]
[MaxLength(32)]
[MinLength(32)]
public string PasswordHash { get; set; }
public int Elo { get; set; }
public bool IsAdmin { get; set; }
public Guid? CurrentTableId { get; set; }
[ForeignKey(nameof(CurrentTableId))]
public virtual GameTable CurrentTable { get; set; }
[InverseProperty(nameof(GameTable.Creator))]
public ICollection<GameTable> CreatedTables { get; } = new HashSet<GameTable>();
}
public class MyDbContext : DbContext
{
public MyDbContext() : base("DbContextCon")
{
Database.SetInitializer<MyDbContext>(new CreateDatabaseIfNotExists<MyDbContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
public virtual DbSet<Account> Accounts { get; set; }
//public virtual DbSet<SecurityToken> SecurityTokens { get; set; }
public virtual DbSet<GameTable> GameTables { get; set; }
}
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());
using (var db = new MyDbContext())
{
db.Database.CreateIfNotExists();
}
Console.WriteLine("Hit any key to exit.");
Console.ReadKey();
}
}
}
It seams you want to create a self reference GameTable table. 它暗示您要创建一个自参考GameTable表。 To do this you need to add a Collection property to Account table like.. 为此,您需要向帐户表中添加一个Collection属性,例如。
public virtual ICollection<GameTable> Children { get; set; }
Whole code block looks like 整个代码块看起来像
public class GameTable
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id
{
get;
set;
}
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
public Guid CreatorId { get; set; }
[ForeignKey(nameof(CreatorId))]
public Account Creator { get; set; }
}
public class Account
{
public Account()
{
Elo = 1000;
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
[MaxLength(15)]
[MinLength(4)]
public string Name { get; set; }
[Required]
[MaxLength(32)]
[MinLength(32)]
public string PasswordHash { get; set; }
public int Elo { get; set; }
public bool IsAdmin { get; set; }
public Guid? CurrentTableId { get; set; }
[ForeignKey(nameof(CurrentTableId))]
public virtual GameTable CurrentTable { get; set; }
public virtual ICollection<GameTable> Children { get; set; }
}
Hope it will solve your problem. 希望它能解决您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.