使用EF7

时间:2016-04-08 19:54:20

标签: c# sql-server entity-framework asp.net-core entity-framework-core

我目前正在清理一个相当大的数据库。数据库的一部分具有一对一或零映射的关系。具体做法是:

User -> UserSettings

并非所有用户都有用户设置,但没有用户就无法存在用户设置。不幸的是,这些表已经存在。 User有一个PK ID。 UserSettings有一个PK ID和一列User_Id_Fk,此时此列不是真正的FK(没有定义任何关系)。

我正在修复它,并且已经通过SQL从数据库角度完成了这一过程并且已通过测试确认。 (添加了FK约束。在User_Id_Fk上添加了一个唯一约束。)这都是在UserSettings表上完成的。 (注意:我这里没有使用EF迁移。我必须在此时手动编写SQL。)

但是,我现在需要连接现有应用程序以正确处理这个新映射。该应用程序使用ASP.NET Core 1.0和EF7。以下是现有数据模型的(缩短版)。

public class User
{
  public int Id { get; set; }

  public virtual UserSettings UserSettings { get; set; }
}

public class UserSettings
{
  public int Id { get; set; }

  [Column("User_Id_Fk")]
  public int UserId { get; set; }

  [ForeignKey("UserId")]
  public virtual User User { get; set; }
}

我也有这个Fluent Mapping:

builder.Entity<UserSettings>()
            .HasOne(us => us.User)
            .WithOne(u => u.User)
            .IsRequired(false);

当我去运行应用程序并访问数据库中的这些项目时,我收到此错误,然后是一组隐藏的消息,这些消息没有直接与我的应用程序相关的信息。:

ArgumentNullException: Value cannot be null.
Parameter name: navigation
Microsoft.Data.Entity.Utilities.Check.NotNull[T] (Microsoft.Data.Entity.Utilities.T value, System.String parameterName) <0x10d28a650 + 0x00081> in <filename unknown>, line 0

经过研究,有人提到UserSettings类的ID必须与外键相同,如下所示:

public class UserSettings
{
  [Key, ForeignKey("User")]
  public int Id { get; set; }

  public virtual User User { get; set; }
}

我没有把它作为一个选项,因为DB正用于我此时无法控制的其他应用程序。那么,我被困在这里了吗?我是否只需要维护一个1:多的映射(现在可以发生,虽然它没有)并且对1:0..1映射没有适当的约束?

更新 看下面的octavioccl的答案,我尝试了没有任何成功。但是,我随后从User中的映射中删除了UserSettings(但我离开了UserId)。就我所知,一切似乎都有效。我真的很困惑这里发生了什么,如果这是正确的答案,或者我只是幸运。

1 个答案:

答案 0 :(得分:4)

删除数据注释并尝试使用以下配置:

builder.Entity<UserSettings>()
            .Property(b => b.UserId)
            .HasColumnName("User_Id_Fk");

builder.Entity<User>()
            .HasOne(us => us.UserSettings)
            .WithOne(u => u.User)
            .HasForeignKey<UserSettings>(b => b.UserId);

来自EF Core documentation

  

配置外键时,需要指定依赖项   实体类型 - 注意提供给HasForeignKey的通用参数   在上面的列表中。在一对多的关系中,很明显   具有参考导航的实体是从属实体和一个实体   与集合是主要的。但事实并非如此   一对一的关系 - 因此需要明确定义它。

quoted linkBlog - BlogImage)中显示的示例与您要实现的内容几乎相同。

如果我上面显示的解决方案不起作用,那么您应该检查User_Id_Fk列是否允许null。如果是这种情况,请将FK属性类型更改为int?

public class UserSettings
{
  public int Id { get; set; }

  public int? UserId { get; set; }

  public virtual User User { get; set; }
}