多列上未定义键的关键字

3

我正在使用C#和Entity Framework。我想将SimulationParameter对象的一个关键字定义为三列(Name、StudyId、SimulationId)的组合。由于这三个元素的组合始终是唯一的,因此我不需要ID列。

模拟参数:

public class SimulationParameter : IAggregateRoot
    {
        public SimulationParameter()
        {
        }

        public String SimulationId { get; set; }

        public Guid StudyId { get; set; }

        public Study Study { get; set; }

        public String Name { get; set; }
        public String Value { get; set; }        
    }

模拟参数映射:

class SimulationParameterMap : EntityTypeConfiguration<SimulationParameter>
    {
        public SimulationParameterMap()
        {
          HasKey(e => new {SimulationId = e.SimulationId, Name = e.Name, StudyId = e.StudyId});            

        Property(e => e.SimulationId)
            .IsRequired(); 

        Property(e => e.Name)
            .IsRequired(); 

        Property(e => e.Value)
            .IsRequired();

        HasRequired(e => e.Study)
            .WithMany(e => e.SimulationsParameters)
            .HasForeignKey(s => s.StudyId);

        ToTable("SimulationParameters");
        }
    }

现在,当我尝试创建模型时,出现以下错误:
    EntityType 'SimulationParameter' has no key defined. Define the key for this EntityType.
SimulationParameters: EntityType: EntitySet 'SimulationParameters' is based on type 'SimulationParameter' that has no keys defined.

我真的不知道为什么这是无效的...

编辑1:

根据建议,在模型中的字段上方添加了[Key]属性:

 public class SimulationParameter : IAggregateRoot
    {
        public SimulationParameter()
        {
        }

        [Key]
        public String SimulationId { get; set; }
        [Key]
        public Guid StudyId { get; set; }

        public Study Study { get; set; }
        [Key]
        public String Name { get; set; }
        public String Value { get; set; }

    }

出现了另一个错误:


System.InvalidOperationException: Unable to determine composite primary key ordering for type 'SimulationParameter'. Use the ColumnAttribute (see http://go.microsoft.com/fwlink/?LinkId=386388) or the HasKey method (see http://go.microsoft.com/fwlink/?LinkId=386387) to specify an order for composite primary keys.

编辑2

我通过以下方式使其工作:

  public class SimulationParameter : IAggregateRoot
    {
        public SimulationParameter()
        {
        }

        [Key, Column(Order=1)]
        public String SimulationId { get; set; }

        [Key, Column(Order = 2)]
        public Guid StudyId { get; set; }

        public Study Study { get; set; }

        [Key, Column(Order = 3)]
        public String Name { get; set; }

        public String Value { get; set; }



    }

尽管使用流畅的方法仍然无法正常工作,这仍然很奇怪。我会继续寻找并及时通知您。


SimulationParameter是哪个类的对象?你能发布一下你的类的代码吗? - Phani
我已经更新了问题并附上了代码。 - Etienne Noël
如果在模型中的每个字段上方添加[Key],会发生什么?你确定它能够识别你的流畅代码吗?那应该可以正常工作。 - John
它识别我的流畅代码,因为如果我不放置多个键,我的数据库就会被创建。我会尝试一下。 - Etienne Noël
我在SimulationId、StudyId和Name上方加上[Key]后,出现了不同的错误。 System.InvalidOperationException: 无法确定类型“SimulationParameter”的复合主键排序方式。请使用ColumnAttribute(请参阅http://go.microsoft.com/fwlink/?LinkId=386388)或HasKey方法(请参阅http://go.microsoft.com/fwlink/?LinkId=386387)指定复合主键的顺序。 - Etienne Noël
应该是 [Key, Column(0)][Key, Column(1)] 等等。 - Gert Arnold
1个回答

1
你不能在另一个类中使用属性作为主键:e.Study.Id。在数据库中,SimulationParameter 也应该有一个 StudyId(或类似的东西)。只需将此字段添加到类中,并使其成为键的一部分即可:
public class SimulationParameter : IAggregateRoot
{
    public SimulationParameter()
    {
    }

    public String SimulationId { get; set; }

    [ForeignKey("Study")]
    public int StudyId { get; set; }
    public Study Study { get; set; }

    public String Name { get; set; }
    public String Value { get; set; }            
}

或者,使用流畅的映射方式:
HasRequired(e => e.Study)
.WithMany(e => e.SimulationsParameters)
.HasForeignKey(s => s.StudyId);

我也在使用Fluent(已更新代码),但是在映射中还需要改变其他什么吗?因为如果按照你的建议将e.Study.Id更改为e.StudyId,我仍然会得到相同的错误。 - Etienne Noël
是的,我需要在映射中添加一些关于StudyId的信息吗? - Etienne Noël
如果我使用Fluent,我是否仍然需要使用ForeignKey? - Etienne Noël
不,不是属性。 - Gert Arnold
仍出现相同的错误... 我已经更新了代码,包括您的修改,如果您发现其他问题,请告诉我,谢谢您抽出时间。 - Etienne Noël

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接