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

tra*_*max 31 c# entity-framework database-migration entity-framework-4

我正在尝试在具有父子关系的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.
 }
Run Code Online (Sandbox Code Playgroud)

这是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.

}
Run Code Online (Sandbox Code Playgroud)

这是我的DBContext的一部分:

public class SiteContext : DbContext
{

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

    public DbSet<UserProjectRole> UserProjectRoles { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我在使用EF 4.3.1的VisualStudio 2012中

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

谢谢你阅读这篇文章 - )

tra*_*max 16

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

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

实体框架4.1至4.3在EntityFramework程序集的System.ComponentModel.DataAnnotations命名空间中包含其他数据注释.在.NET 4.5中,这些注释被移动到System.ComponentModel.DataAnnotations.dll程序集的System.ComponentModel.DataAnnotations.Schema命名空间中的.NET Framework的一部分.如果您使用的是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
  • 最长长度
  • 使用MINLENGTH
  • NotMapped

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

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

这个截屏视频是更新到EF5.0的绝佳起点

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

package id="EntityFramework" version="5.0.0-rc" targetFramework="net40" 
Run Code Online (Sandbox Code Playgroud)

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

我希望这能挽救一些人在墙上敲头.


A. *_* Gh 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; }
}
Run Code Online (Sandbox Code Playgroud)

试试这个,特别是[Required]上面的public Project Project {get; set;}.

如果这不起作用,请再次尝试并删除[Key, Column (Order = 1)]上面的[ForeignKey("ProjectID")]

  • 这个解决方案帮助了我,感谢发布.PS.发布问题的替代解决方案非常有帮助,即使它们已经老化并且之前已经解决了. (4认同)

Cas*_*sen 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>
Run Code Online (Sandbox Code Playgroud)

<Reference Include="EntityFramework">
  <HintPath>..\packages\EntityFramework.5.0.0\lib\net45\EntityFramework.dll</HintPath>
</Reference>
Run Code Online (Sandbox Code Playgroud)

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