使用ColumnAttribute或HasKey方法指定组合主键的顺序

时间:2012-08-11 00:52:39

标签: c# entity-framework entity-framework-4 database-migration

我正在尝试在具有父子关系的2个对象上使用复合主键。每当我尝试创建新的迁移时,都会收到错误:

无法确定“Models.UserProjectRole”类型的复合主键排序。使用ColumnAttribute或HasKey方法指定复合主键的顺序。

根据错误提示,我确实添加了注释Column (Order = X),但错误仍然存​​在并且不会消失,除非我只留下一个带有Key注释的字段。 以下是我的目标:

public class UserProjectRole
{
    [Key, Column(Order = 0),DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid UserProjectRoleID { get; set; }

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

    [ForeignKey("ProjectID")]
    public Project Project { get; set; }

    public Guid AppUserGuid { get; set; }

    // followed by a number of unrelated String fields.
 }

这是Project类:

public class Project: Base
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid ProjectID { get; set; }

    public virtual ICollection<UserProjectRole> UserRoles { get; set; }

    // followed by a number of unrelated String fields.

}

这是我的DBContext的一部分:

public class SiteContext : DbContext
{

    public DbSet<Project> Projects { get; set; }

    public DbSet<UserProjectRole> UserProjectRoles { get; set; }
}

我在Visual Studio 2012中使用EF 4.3.1

我一直在讨论这个问题已经有一段时间了,所有的论坛和SO答案都建议添加我已经拥有的Column Order注释。 我错过了一些明显的东西吗?

感谢您阅读此内容 - )

4 个答案:

答案 0 :(得分:16)

花了很多时间来测试和测试不同的东西。直到我决定从头开始创建具有类似数据结构的新vanilla项目之前,我一无所知。 当我从NuGet安装EntityFramework时,我看到了一条消息:

  

Entity Framework 4.x和.NET Framework 4.5的已知问题

     

实体框架4.1至4.3包含了额外的数据注释   中的System.ComponentModel.DataAnnotations命名空间   EntityFramework程序集。在.NET 4.5中,这些注释被移动到   成为.NET Framework的一部分   System.ComponentModel.DataAnnotations.Schema的命名空间   System.ComponentModel.DataAnnotations.dll程序集。如果你正在使用   EF 4.x并以.NET 4.5为目标,这会产生两个数据注释   在不同的程序集中具有相同的名称。因为注释在   .NET Framework位于我们无法使用的不同命名空间中   使用类型转发来避免这种冲突。

     

可以在.NET 4.5上使用EF 4.x,但我们建议使用   EF 5的最新预发布版本。如果您没有使用受影响的版本   数据注释对您的代码没有影响。如果你正在使用   在C#项目中的数据注释,您可以使用extern修饰符   确保您的代码使用EntityFramework.dll中的注释   (http://msdn.microsoft.com/en-us/library/e59b22c5(v=VS.80).aspx)。如果   你使用的新注释   .NET 4.5中的System.ComponentModel.DataAnnotations.dll程序集   不会被Code First处理。

     

受影响的注释是:

     
      
  •   
  • 的ComplexType
  •   
  • DatabaseGenerated
  •   
  • DatabaseGeneratedOption
  •   
  • ForeignKey的
  •   
  • InverseProperty
  •   
  • 的MaxLength
  •   
  • MINLENGTH个
  •   
  • NotMapped
  •   
  •   

此时我意识到我的数据项目是在VS2012中新创建的,默认情况下是.Net 4.5,我的项目中的其余项目是从VS2010迁移到目标.Net 4.0。 所以我更新了所有项目以.Net 4.5为目标,并获得了EntityFramework 5.0的预发布。

确保先将项目更新为Net4.5,之后将EF更新为5.0,否则会永远恨你,许多兔子会死。

This screencast是更新到EF5.0

的绝佳起点

<击> 那时我的错误消失了,但我变得与众不同了。我无法添加迁移,因为它无法找到迁移配置,即使我在其前几秒设置了配置。 这再次耗费了大量的NuGet,卸载了广告重新安装包。 然后我在packages.config行中看到如下:

package id="EntityFramework" version="5.0.0-rc" targetFramework="net40" 

我已将targetFramework更改为“net45”,现在我从迁移中获得了预期的行为。我想有更好的方法来获得带有软件包的nuget目标.Net 4.5,但这对我有用。

我希望这会挽救有人在墙上敲头。

答案 1 :(得分:9)

    public class UserProjectRole
    {
        [Key, Column (Order = 0)]
        public Guid UserProjectRoleID { get; set; }

    [Key, Column (Order = 1)]
    [ForeignKey("Project")]
    public Guid ProjectID { get; set; }

    [Required]
    public Project Project { get; set; }

    public Guid AppUserGuid { get; set; }

    // followed by a number of unrelated String fields.
 }

public class Project: Base
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid ProjectID { get; set; }

    public virtual ICollection<UserProjectRole> UserRoles { get; set; }

    // followed by a number of unrelated String fields.

}

    public class SiteContext : DbContext
{

    public DbSet<Project> Projects { get; set; }

    public DbSet<UserProjectRole> UserProjectRoles { get; set; }
}

尝试此操作,尤其是[Required]上方的public Project Project {get; set;}

如果这不起作用,请再次尝试并移除[Key, Column (Order = 1)]

上方的[ForeignKey("ProjectID")]

答案 2 :(得分:6)

以下是那些有死兔子的人(在更新到.Net 4.5之前更新到EF 5.0):

在csproj文件中,更改

<Reference Include="EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\packages\EntityFramework.5.0.0\lib\net40\EntityFramework.dll</HintPath>
</Reference>

<Reference Include="EntityFramework">
  <HintPath>..\packages\EntityFramework.5.0.0\lib\net45\EntityFramework.dll</HintPath>
</Reference>

当你知道它时非常明显......

答案 3 :(得分:2)

我能够使用

找到相同的解决方案

PM&GT; Install-Package EntityFramework -Pre

http://weblogs.asp.net/scottgu/archive/2012/12/11/entity-framework-6-alpha2-now-available.aspx