使用外键作为主键

时间:2013-10-08 14:05:00

标签: c# entity-framework foreign-keys primary-key ef-database-first

我有一个有很多关系的数据库。不幸的是,它是一个旧的维护数据库,它似乎不理解关联或密钥的概念,它有时缺乏。它的主要用途是在另一个应用程序中,因此我最不愿意更改数据库(而是配置实体框架)

我遇到的问题是尝试使用外键作为主键,因为(我猜)关联表使用它。

我的表名为

Operation{    Criteria {    Parameter{    CriteriaSelection {
  ID            ID,           ID,           ID,
  ..            ..            ..            ..
}             }             }             }

CheckpointOperation {
  ID,
  Criteria_ID,
  ..
}

CheckpointParameter {
  // missing primary key
  CheckpointOperation_ID,  // a CheckpointOperation has many CheckpointParameters
  CriteriaSelection_ID,    // a CheckpointParameter has one CriteriaSelection
  Parameter_ID,            // .. and one Parameter
  ..
}

此处的问题是CheckpointParameter没有专门定义任何主键,而是{ CheckpointOperation_ID, CriteriaSelection_ID, Parameter_ID }的主键。现在我尝试使用class CheckpointParameterMap : EntityTypeConfiguration<CheckpointParameter>在EntityFramework中映射它。

public class CheckpointOperation
{
    public int Id { get; set; }
    public virtual Operation Operation { get; set; }

    public virtual ICollection<CheckpointParameter> Parameters { get; set; }
}

public class CheckpointParameter
{
    public int OperationId { get; set; }

    public virtual CheckpointOperation CheckpointOperation { get; set; }
    public virtual CriteriaSelection Criteria { get; set; }
    public virtual QualityParameter Parameter { get; set; }
}

public class CheckpointParameterMap : EntityTypeConfiguration<CheckpointParameter>
{
    public CheckpointParameterMap()
    {
        HasKey(p => new { p.OperationId });

        Property(p => p.OperationId)
            .HasColumnName("CheckpointOperation_ID");

        HasRequired(p => p.CriteriaSelection)
            .WithRequiredDependent()
            .Map(map => map.MapKey("CriteriaSelection_ID"));

        HasRequired(p => p.Parameter)
            .WithRequiredDependent()
            .Map(map => map.MapKey("Parameter_ID"));

        HasRequired(p => p.CheckpointOperation)
            .WithMany(o => o.CheckpointParameters)
            .HasForeignKey(p => p.OperationId);
    }
}

但这给我一个错误

  

Multiplicity在关系'CheckpointParameter_CheckpointOperation'中的角色'CheckpointParameter_CheckpointOperation_Source'中无效。由于从属角色是指关键属性,因此从属角色的多重性的上限必须为“1”。\ r \ n“}

所以我尝试删除了HasKey,但这给了我一个错误

  

EntityType'CheckpointParameter'没有定义键。定义此EntityType的键。\ r \ n \ tSystem.Data.Entity.Edm.EdmEntitySet:EntityType:EntitySet'CheckpointParameters'基于类型'CheckpointParameter',没有定义键。\ r \ n“}

然后我尝试在主键中使用外来的CriteriaSelectionId,因为我有列名:

public class CheckpointParameter
{
    ...
    public int CriteriaSelectionId { get; set; }
    ...
}

public CheckpointParameterMap()
{
    HasKey(p => new { p.OperationId, p.CriteriaSelectionId });
    //...
    Property(checkpointParameter => checkpointParameter.CriteriaSelectionId)
        .HasColumnName("CEC_ID");
}

但是这给了我以下错误:

  

{“指定的模式无效。错误:\ r \ n(48,6):错误0019:类型中的每个属性名称必须是唯一的。属性名称'CriteriaSelection_ID'已经定义。”}

在不修改数据库的情况下,定义主键(外键)的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您需要在Mapping的Criteria and Operation中添加哪个字段作为参考:

this.HasKey(x => x.OperationId); // In Operation Mapping

this.HasKey(x => x.CriteriaId); // In Criteria Mapping

在Criteria或Operation中你应该映射一些这样的东西:

this.HasMany(b => b.Criterias)
    .WithMany( x=> x.Operations)
    .Map(x =>
    {
        x.ToTable("CheckpointParameter");
        x.MapLeftKey("CriteriaId");
        x.MapRightKey("OperationId");
    });