【问题标题】:Entity Framework: One to zero/one with C# Code First实体框架:一对零/使用 C# 代码优先
【发布时间】:2013-08-14 06:17:22
【问题描述】:

如果这个问题已经在某处得到解答,请提前抱歉,但我四处搜索并找不到答案。

我正在尝试链接 UserProfile 和 Reviewer 表。 Reviewer是应用程序中的一类用户,所以两张表的关系是一(UserProfile)到零/一(Reviewer)。

UserProfile 模型是:

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }

    public virtual Reviewer Reviewer { get; set; }
} 

审稿人等级:

public class Reviewer
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    [ForeignKey("UserProfile")]
    public int ReviewerID { get; set; }

    public string Email { get; set; }
    // other properties of Reviewer...

    public virtual UserProfile UserProfile { get; set; }

}

换句话说,我正在尝试将外键 UserId 设置为表 Reviewer 的键,名称为 ReviewerID。

我指定fluent API如下:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        // other fluent API...

        modelBuilder.Entity<UserProfile>()
                .HasOptional(x => x.Reviewer).WithRequired(x => x.UserProfile);

    }

但是,Code First 生成的数据库并不是我想要的。

假设我在 UserProfile 表中有以下条目: UserId = 4, UserName = lostman1

我尝试手动将新记录插入到 Reviewer 表中: ReviewerID = 4,电子邮件 = d@d.com

事实证明,我无法更新数据库中的 ReviewerID 字段,因为它是一个自动递增的字段。此外,我收到以下错误:

第 4 行的数据未提交。
错误来源:SQL Server Compact ADO.NET 数据提供程序。
错误消息:无法插入外键值,因为相应的主键 > 值不存在。 [外键约束名=FK_dbo.Reviewer_dbo.UserProfile_ReviewerID]

我的代码首次设置有什么问题?非常感谢!

【问题讨论】:

  • 用你的流利的方式尝试这样的事情,并在你的用户配置文件中添加一个外键int? ReviewerIdHasOptional(t =&gt; t.Organization) .WithMany(t =&gt; t.Configurations) .HasForeignKey(d =&gt; d.OrganizationID);
  • 对不起,我是 asp.net MVC 的新手。我尝试:modelBuilder.Entity().HasOptional(x => x.Reviewer).WithRequired(x => x.UserProfile).HasForeignKey(d => d.UserId);但它返回编译错误。你能帮我写下我需要输入的确切流畅的 API 语句,或者指出我正确的方向吗?谢谢。

标签: c# asp.net-mvc entity-framework ef-code-first


【解决方案1】:

在我看来,您需要在 Reviewer 和 User 之间建立 UserID FK 关系。在这样的设计中,并非所有用户都必须是审阅者,但所有审阅者都必须是用户。

我也开始认为,您可能因为没有在系统中使用角色概念而使事情变得过于复杂。通常,将根据用户具有的角色指定用户与审阅者。这样,所有用户都是相同的,并且在表中保存相同的数据,唯一的区别是用户具有不同的角色。

使用角色与执行复杂的表连接或可为空的 FK 关系相比,授权和身份验证也变得更加简单。

【讨论】:

  • 感谢您的建议。事实上,在我的应用程序中有不同类型的用户,例如 Approver。但是,不同类型的用户与其他表的关系不同。例如,表 Reviewer 与表 Reviewer_class 具有多对一关系,而表 Approver 与 Approver_class 具有多对一关系。如果我只是将不同的用户类型分配给不同的角色,我无法封装这种差异,我还需要链接数据库中的表来表示这些关系。它是否正确?谢谢。
  • 我明白你在说什么,但你的设计可以用更小的连接表和角色来完成。例如,您可以有一个连接表,将用户与评论连接起来,然后让角色管理确定用户是否是评论者。
  • 对不起,我是 web 编程和 asp.net 的新手,所以我不太明白。角色管理如何确定用户是否是审阅者?事实上,我的应用程序中有多种类型的用户,每种类型都有不同类型的配置文件(存储有不同的用户详细信息)以及与其他实体的关系。我认为角色管理仅用于授权有权访问资源的人。我如何在这方面使用它来帮助我?有没有关于你提到的任何教程?谢谢。
  • 您可能需要查看this 进行角色管理。
【解决方案2】:

不确定你的问题是否解决了,如果没有,你可以试试这样的方法

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasOptional(x => x.Reviewer).WithRequired(x => x.User).Map(x => x.MapKey("UserId"));
        base.OnModelCreating(modelBuilder);
    }

这是我的模型声明

public class User
{
    [Key]
    public int UserId { get; set; }
    public string UserName { get; set; }

    public virtual Reviewer Reviewer { get; set; }
}
public class Reviewer
{
    [Key]
    public int ReviewerId { get; set; }

    public virtual User User { get; set; }
}

【讨论】:

    猜你喜欢
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 2014-05-23
    相关资源
    最近更新 更多