EF6 代码第一个模型 ForeignKey

EF6 Code first model ForeignKey

当我尝试从后续模型生成数据库时遇到异常。

The ForeignKeyAttribute on property 'DataCenterBenchmark' on type 'Benchmark.Data.Context' is not valid. The foreign key name 'BenchmarkId' was not found on the dependent type 'Benchmark.Data.Context'. The Name value should be a comma separated list of foreign key property names.

[Table("Contexts")]
public class Context
{
    [Key]
    public Guid InternalId { get; set; }

    [Required] public string Name { get; set; }
    [Required] public string Cluster { get; set; }
    [Required] public string Token { get; set; }
    [Required] public string IP { get; set; }
    [Required] public string Memo { get; set; }
    [Required] public string BenchType { get; set; }

    [Required] public int InstanceCount { get; set; }
    [Required] public int ThreadCount { get; set; }
    [Required] public int RequestCount { get; set; }

    [Required] public DateTime CreationDate { get; set; }
    [Required] public DateTime EditDate { get; set; }

    [ForeignKey("BenchmarkId")]
    public Benchmark RemoteBenchmark { get; set; }
    [ForeignKey("BenchmarkId")]
    public Benchmark DataCenterBenchmark { get; set; }
    [ForeignKey("BenchmarkId")]
    public Benchmark IISBenchmark { get; set; }
    [ForeignKey("BenchmarkId")]
    public Benchmark LocalBenchmark { get; set; }

    [ForeignKey("MachineTypeId")]
    [Required] public MachineType MachineType { get; set; }
}

[Table("Benchmarks")]
public class Benchmark
{
    [Key]
    public int BenchmarkId { get; set; }
    [Required] public string Result { get; set; }
    [Required] public DateTime Duration { get; set; }
}

[Table("MachineTypes")]
public class MachineType
{
    [Key]
    public int MachineTypeId { get; set; }
    [Required] public string Name { get; set; }
}

public class BenchmarkContext : DbContext
{
    public DbSet<Context> Contexts { get; set; }
    public DbSet<Benchmark> Benchmarks { get; set; }
    public DbSet<MachineType> MachineTypes { get; set; }
}

尝试通过一些教程修复它 - 没有成功..

此致, 马克

===== 编辑 =====

删除 [ForeignKey] 标志后,我无法连接到我的 SQL 服务器(错误 26)。我没有将数据库设置为连接字符串,因此 EF6 需要创建一个 localdb..?

您可以覆盖 OnModelCreating 方法 BenchmarkContext 并编写如下表之间的关系。

注意:您需要删除属性[ForeignKey("BenchmarkId")]

public class BenchmarkContext : DbContext
{
    public DbSet<Context> Contexts { get; set; }
    public DbSet<Benchmark> Benchmarks { get; set; }
    public DbSet<MachineType> MachineTypes { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Context>()
            .HasRequired(m => m.RemoteBenchmark)
            .WithOptional()
            .Map(m => { m.MapKey("RemoteBenchmarkId"); });

        modelBuilder.Entity<Context>()
            .HasRequired(m => m.DataCenterBenchmark)
            .WithOptional()
            .Map(m => { m.MapKey("DataCenterBenchmarkId"); });

        modelBuilder.Entity<Context>()
            .HasRequired(m => m.IISBenchmark)
            .WithOptional()
            .Map(m => { m.MapKey("IISBenchmarkId"); });

        modelBuilder.Entity<Context>()
            .HasRequired(m => m.LocalBenchmark)
            .WithOptional()
            .Map(m => { m.MapKey("LocalBenchmarkId"); });
    }
}

外键快速指南属性。

在键属性(例如int RemoteBenchmarkId)上使用时,其名称应指向导航属性(例如Benchmark RemoteBenchmark)。 当用于导航 属性(这次是 Benchmark RemoteBenchmark)时,它的名称应该指向键 属性(例如 int RemoteBenchmarkId)。

以下代码片段是等价的:

public class Context {
    //...other properties

    [ForeignKey("RemoteBenchmark")]
    public int RemoteBenchmarkId { get; set; }
    public Benchmark RemoteBenchmark { get; set; }
    }
public class Context {
    //...other properties

    public int RemoteBenchmarkId { get; set; }

    [ForeignKey("RemoteBenchmarkId")]
    public Benchmark RemoteBenchmark { get; set; }
    }

考虑到这一点,您可能想要的是 4 个基准,每个基准都有自己的外键列(使用相同键的两个基准属性将指向同一个实例,这可能不是您想要的),就像这里:

public class Context {
    //...other properties

    [ForeignKey("RemoteBenchmark")]
    public int RemoteBenchmarkId { get; set; }
    public Benchmark RemoteBenchmark { get; set; }

    [ForeignKey("DataCenterBenchmark")]
    public int DataCenterBenchmarkId { get; set; }
    public Benchmark DataCenterBenchmark { get; set; }

    [ForeignKey("IISBenchmark")]
    public int IISBenchmarkId { get; set; }
    public Benchmark IISBenchmark { get; set; }

    [ForeignKey("LocalBenchmark")]
    public int LocalBenchmarkId { get; set; }
    public Benchmark LocalBenchmark { get; set; }
    }

如果上下文需要特定基准,请不要忘记使用 [Required] 注释!

此外,您可能会跳过 [ForeignKey] 注释,完全允许 ​​EF 自行推断列(默认情况下命名为 <navigation property name>_Id,例如 RemoteBenchmark_Id),但您无法检索ids 本身而不检索整个基准。猜猜这一切都取决于具体情况;就个人而言,我不介意具有外键属性的混乱模型,因为有时键本身就足够了。

(至少 [ForeignKey] 个注释 不应该 是必要的;如果它们的缺少导致错误,那可能完全是另一个问题...?)

干杯~!