C# 使用 ColumnAttribute 或 HasKey 方法指定复合主键的顺序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11910962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 19:42:43  来源:igfitidea点击:

Use the ColumnAttribute or the HasKey method to specify an order for composite primary keys

c#entity-frameworkentity-framework-4database-migration

提问by trailmax

I'm trying to use composite primary key on 2 objects with parent-child relationship. Whenever I try to create a new migration, I get an error:

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

Unable to determine composite primary key ordering for type 'Models.UserProjectRole'. Use the ColumnAttribute or the HasKey method to specify an order for composite primary keys.

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

As per error suggests, I do add annotation Column (Order = X)but the error still there and does not go away, unless I leave only one field with Key annotation. Here is my object that it trips off:

根据错误提示,我确实添加了注释,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.
 }

Here is Project class:

这是项目类:

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.

}

Here is part of my DBContext:

这是我的 DBContext 的一部分:

public class SiteContext : DbContext
{

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

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

I'm in VisualStudio 2012 with EF 4.3.1

我在使用 EF 4.3.1 的 VisualStudio 2012

I have been banging my head against this for a while now and all the forum and SO answers suggest to add Column Order annotation that I already have. Am I missing something obvious???

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

Thank you for reading this far -)

感谢您阅读到这里-)

采纳答案by trailmax

It took a lot of fiddling about and testing different things. I was clueless until I decided to make a new vanilla project with the similar data structure from scratch. And when I installed EntityFramework from NuGet, I was shown a message:

这需要大量摆弄和测试不同的东西。我一无所知,直到我决定从头开始创建一个具有类似数据结构的新项目。当我从 NuGet 安装 EntityFramework 时,我看到了一条消息:

Known Issues with Entity Framework 4.x and .NET Framework 4.5

Entity Framework 4.1 thru 4.3 included additional data annotations in the System.ComponentModel.DataAnnotations namespace in the EntityFramework assembly. In .NET 4.5 these annotations were moved to be part of the .NET Framework in the System.ComponentModel.DataAnnotations.Schema namespace of the System.ComponentModel.DataAnnotations.dll assembly. If you are using EF 4.x and targeting .NET 4.5 this results in two data annotations with the same name in different assemblies. Because the annotations in the .NET Framework are in a different namespace we were not able to use type forwarding to avoid this conflict.

It is possible to use EF 4.x on .NET 4.5 but we recommend using the latest pre-release version of EF 5. If you are not using the affected data annotations there is no impact on your code. If you are using the data annotations in a C# project you can use the extern modifier to ensure your code uses the annotations from EntityFramework.dll (http://msdn.microsoft.com/en-us/library/e59b22c5(v=VS.80).aspx). If you use the new annotations from the System.ComponentModel.DataAnnotations.dll assembly in .NET 4.5 they will not be processed by Code First.

The affected annotations are:

  • Column
  • ComplexType
  • DatabaseGenerated
  • DatabaseGeneratedOption
  • ForeignKey
  • InverseProperty
  • MaxLength
  • MinLength
  • NotMapped
  • Table

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

Entity Framework 4.1 到 4.3 在 EntityFramework 程序集中的 System.ComponentModel.DataAnnotations 命名空间中包含了额外的数据注释。在 .NET 4.5 中,这些注释被移到 System.ComponentModel.DataAnnotations.Schema 命名空间中 System.ComponentModel.DataAnnotations.dll 程序集的 .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 处理。

受影响的注释是:

  • 柱子
  • 复杂类型
  • 数据库生成
  • 数据库生成选项
  • 外键
  • 反性质
  • 最长长度
  • 最小长度
  • 未映射
  • 桌子

At that point I realised that my data project was freshly created in VS2012 and was by default targeting .Net 4.5 and the rest of my project in solutions were migrated from VS2010 and targeting .Net 4.0. So I have updated all the projects to target .Net 4.5 and got the pre-release of EntityFramework 5.0.

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

Make sure you update your projects first to Net4.5, after that do update EF to 5.0, otherwise it will hate you forever and many bunnies will die.

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

This screencastis a great starter for updating to EF5.0

此截屏视频是更新到 EF5.0 的绝佳开端

At that point my error was gone, but I was getting different one. I could not add migration because it could not find Migration Configuration, even though I had configuration set up just seconds before it. That again took a lot of fiddling with NuGet, uninstalling ad re-installing packages. Then I saw in packages.config lines like this:

那时我的错误消失了,但我得到了不同的错误。我无法添加迁移,因为它找不到迁移配置,即使我在它之前几秒钟就设置了配置。这再次需要大量摆弄 NuGet,卸载广告重新安装包。然后我在packages.config中看到这样的行:

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

I have changed targetFrameworkto "net45" and now I'm getting the expected behavior from migrations. I guess there would be a better way to get nuget target .Net 4.5 with packages, but that's what worked for me.

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

I hope this will save somebody banging their head on a wall.

我希望这能避免有人用头撞墙。

回答by Casper Leon Nielsen

Here is the fix for those with dead bunnies (having updated to EF 5.0 before updating to .Net 4.5):

这是针对死兔子的修复程序(在更新到 .Net 4.5 之前已更新到 EF 5.0):

In the csproj files, change

在 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>

TO

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

Pretty obvious when you know it....

当你知道的时候很明显......

回答by James Fleming

I was able to come to the same solution using

我能够使用相同的解决方案

PM> Install-Package EntityFramework -Pre

PM> Install-Package EntityFramework -Pre

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

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

回答by Abed G.

    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; }
}

Try this, especially with the [Required]above the public Project Project {get; set;}.

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

If this doesn't work, try it again and remove the [Key, Column (Order = 1)]above the [ForeignKey("ProjectID")]

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