EF6 Code第一个型号为ForeignKey

时间:2015-03-31 11:30:26

标签: c# entity-framework database-design foreign-keys

当我尝试从跟随的模型生成数据库时,我得到了一个例外。

  

类型上属性'DataCenterBenchmark'上的ForeignKeyAttribute   'Benchmark.Data.Context'无效。外键   在依赖类型上找不到名称“BenchmarkId”   'Benchmark.Data.Context'。 Name值应为a   以逗号分隔的外键属性名称列表。

[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 Server(错误26)。我没有设置数据库作为连接字符串,所以EF6需要创建一个localdb ..?

2 个答案:

答案 0 :(得分:1)

您可以在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"); });
    }
}

答案 1 :(得分:1)

通过ForeignKey属性的快速指南。

在密钥属性(例如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个基准测试,每个基准测试都有自己的外键列(使用相同键的两个基准测试属性将指向相同的实例,这可能不是您想要的),如下所示:< / p>

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]注释不应该;如果他们的缺乏导致错误,那么可能完全是另一个问题......?)

干杯〜!