簡體   English   中英

EF代碼第一個外鍵關系

[英]EF Code First Foreign Key Relationship

我有以下情況:

  • 我有一些帳戶和一些游戲桌。
  • 每個游戲桌都有一個創建者。
  • 每個帳戶都可以坐在桌子上(但不是必須)。

我的模型類如下所示:

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

我的上下文當前看起來像這樣:

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

不幸的是,這不適用於像這樣設置的兩個外鍵。 以下消息目前讓我有些頭疼:

System.InvalidOperationException:'無法確定類型'namespace.GameTable'和'namespace.Account'之間的關聯的主要終點。 必須使用關系流利的API或數據注釋顯式配置此關聯的主要端。

但是,當我注釋掉FK關系之一時,一切都很好。 似乎這兩者之間存在某種沖突。

我想獲得的結果是一個可空FK在Account名為CurrentTableId和非空的FK GameTable所謂CreatorId

在FK關系的每一側,您都可以(通常應該)具有導航屬性。 並且當存在多個FK關系時,可以使用InversePropertyAttribute指定一對導航屬性代表哪個FK。

例如

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

暗示您要創建一個自參考GameTable表。 為此,您需要向帳戶表中添加一個Collection屬性,例如。

public virtual ICollection<GameTable> Children { get; set; }

整個代碼塊看起來像

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

希望它能解決您的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM