【问题标题】:Can Entity Framework produce a mapping from foreign key to a GUID in the parent table?实体框架能否生成从外键到父表中 GUID 的映射?
【发布时间】:2014-09-23 15:09:31
【问题描述】:

我的数据库有两个这样的表(为了简单起见,删除了一些列)

CREATE TABLE [dbo].[Question] (
    [QuestionId]       INT              IDENTITY (1, 1) NOT NULL,
    [ProblemId]        INT              NOT NULL,
    [QuestionUId]      UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
    CONSTRAINT [PK_Question] PRIMARY KEY CLUSTERED ([QuestionId] ASC)
);

CREATE UNIQUE NONCLUSTERED INDEX [Question_QuestionUId_UIX]
    ON [dbo].[Question]([QuestionUId] ASC);

CREATE TABLE [dbo].[AdminTestQuestion] (
    [AdminTestQuestionId] INT              IDENTITY (1, 1) NOT NULL,
    [AdminTestId]         INT              NOT NULL,
    [QuestionNumber]      INT              NOT NULL,
    [QuestionUId]         UNIQUEIDENTIFIER NOT NULL,
    CONSTRAINT [PK_AdminTestQuestion] PRIMARY KEY CLUSTERED ([AdminTestQuestionId] ASC),
    CONSTRAINT [FK_AdminTestQuestionQuestionUId] FOREIGN KEY ([QuestionUId]) REFERENCES [dbo].[Question] ([QuestionUId])
);

当我运行实体框架逆向工程时,它不会从 AdminTestQuestion 创建映射 > 问题 并且它不会在 Question 类中创建 AdminTestQuestions 的集合。我希望看到这样的东西,但据我了解,当外键的一端是 GUID 时,它会遇到困难。

public partial class Question
{
    public Question()
    {
        this.Answers = new List<AdminTestQuestion>();
    }
    public int QuestionId { get; set; }
    public int ProblemId { get; set; }
    public System.Guid QuestionUId { get; set; }
}

我还希望在 AdminTestQuestion 映射文件中出现类似这样的映射信息:

        this.HasRequired(t => t.QuestionUId)
            .With????(t => t.Questions)
            .HasForeignKey(d => d.QuestionUId);

谁能告诉我我可以用 EF6+ 创建这种到 GUID 的映射吗?

【问题讨论】:

  • 数据库中的其他关系是否创建了 GUID 之间的映射?
  • 也许只有我一个人,但你为什么不使用 QuestionID 作为 FK 字段?在整数上 JOi​​ns 将比 guid 快得多。老实说,我不明白为什么你有 GUID 字段,因为你在主表上有不同的 PK。什么是 GUID?
  • QuestionId 仅供内部使用。 QuestionUId 对所有人可见。不幸的是,我只能链接到 QuestionUId。
  • Unique Constraint (i.e. Candidate Key) Support 我们正在努力在 EF7 中提供独特的约束支持。 - 管理员评论
  • 但是使用 EF7 我可以链接到唯一的 System.Guid 吗?

标签: asp.net sql-server entity-framework


【解决方案1】:

EF6 无法做到这一点,因为它不知道 QuestionUId 列上的唯一索引。做到这一点的唯一方法是让 QuestionUId 成为 Question 表中的主键,我认为没有什么可以阻止您这样做:

CREATE TABLE [dbo].[Question] (
    [QuestionId]       INT              IDENTITY (1, 1)  NOT NULL,
    [ProblemId]        INT              NOT NULL,
    [QuestionUId]      UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
    CONSTRAINT [PK_Question] PRIMARY KEY CLUSTERED ([QuestionUId] ASC)
);

CREATE TABLE [dbo].[AdminTestQuestion] (
    [AdminTestQuestionId] INT              IDENTITY (1, 1) NOT NULL,
    [AdminTestId]         INT              NOT NULL,
    [QuestionNumber]      INT              NOT NULL,
    [QuestionUId]         UNIQUEIDENTIFIER NOT NULL,
    CONSTRAINT [PK_AdminTestQuestion] PRIMARY KEY CLUSTERED ([AdminTestQuestionId] ASC),
    CONSTRAINT [FK_AdminTestQuestionQuestionUId] FOREIGN KEY ([QuestionUId]) REFERENCES [dbo].[Question] ([QuestionUId])
);

哪个生成(使用数据库中的 Code First):

public partial class Question
{
    public Question()
    {
        AdminTestQuestion = new HashSet<AdminTestQuestion>();
    }
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int QuestionId { get; set; }
    public int ProblemId { get; set; }
    [Key]
    public Guid QuestionUId { get; set; }
    public virtual ICollection<AdminTestQuestion> AdminTestQuestion { get; set; }
}

public partial class AdminTestQuestion
{
    public int AdminTestQuestionId { get; set; }
    public int AdminTestId { get; set; }
    public int QuestionNumber { get; set; }
    public Guid QuestionUId { get; set; }
    public virtual Question Question { get; set; }
}


protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Question>()
    .HasMany(e => e.AdminTestQuestion)
    .WithRequired(e => e.Question)
    .WillCascadeOnDelete(false);
}

【讨论】:

  • 谢谢埃里克。我是否看到您提到了有关此问题在 6.1.2 中已修复的内容。如果有帮助,我可以轻松升级。
  • 是的,但是 6,1,2 中的修复并不能解决您的问题,遗憾的是 entityframework.codeplex.com/workitem/667
  • EF7 怎么样,或者问这个问题有点太早了?
  • 是的,我认为它可能在 EF7 中工作,因为索引现在是模型的一部分,所以 EF 了解它们
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
相关资源
最近更新 更多