【问题标题】:How to set ForeignKey and Index properties using IEntityTypeConfiguration in EF Core 2.0如何在 EF Core 2.0 中使用 IEntityTypeConfiguration 设置 ForeignKey 和 Index 属性
【发布时间】:2017-11-15 12:08:01
【问题描述】:

我正在尝试使用 EF Core 2.0 中新增的 EntityConfiguration 接口。

附录可能有助于查看 Message 类

public class Message 
{
    public int MessageId { get; set; }

    [Required]
    public string MessageForUserId { get; set; }
    public virtual ApplicationUser MessageForUser { get; set; }

    [Required]
    public string MessageFromUserId { get; set; }

    public virtual ApplicationUser MessageFromUser { get; set; }

    [Required]
    public string MessageContent { get; set; }

    public bool MessageRead { get; set; }

    [Required]
    public DateTime MessageCreatedOn { get; set; }

    public DateTime? MessageReadOn { get; set; }
}

和 AppUser 类

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
    public Gender Gender { get; set; }
    public SubscriptionLevel SubscriptionLevel { get; set; }
    public NotificationType NotificationType { get; set; }
    public string AvatarUrl { get; set; }
    public ICollection<Message> UserMessages { get; set; }
    public ICollection<Message> SentMessages { get; set; }
    public ICollection<IdentityUserClaim<string>> Claims { get;  set; }
}

这是在我的OnModelCreating 方法中定义实体的方式。

builder.Entity<Message>()
            .HasOne(x => x.MessageForUser)
            .WithMany(x => x.UserMessages)
            .HasForeignKey(x => x.MessageForUserId)
            .OnDelete(DeleteBehavior.Restrict);

builder.Entity<Message>()
            .HasOne(x => x.MessageFromUser)
            .WithMany(x => x.SentMessages)
            .HasForeignKey(x => x.MessageFromUserId)
            .OnDelete(DeleteBehavior.Cascade);

我的 IEntityTypeConfiguration

public class AppUserConfig : IEntityTypeConfiguration<ApplicationUser>
{
    public void Configure(EntityTypeBuilder<ApplicationUser> builder)
    {           
        builder.Property(u => u.FirstName).HasMaxLength(31);
        builder.Property(u => u.FirstName).IsRequired();

        builder.Property(u => u.LastName).HasMaxLength(55);
        builder.Property(u => u.LastName).IsRequired();

        builder.Property(u => u.DateOfBirth).HasColumnType("datetime");
        builder.Property(u => u.DateOfBirth).IsRequired();

        builder.Property(u => u.Gender).IsRequired();
    }
}

EF 6 方式有一个 HasForeignKey 方法关闭构建器,该方法不再可用,我似乎找不到任何方法来添加它们。

以下是迁移从我的OnModelCreating 方法构建表的方式。我想把这些项目中的大部分放在我的配置类中。

migrationBuilder.CreateIndex(
            name: "IX_Messages_MessageForUserId",
            schema: "AppContext",
            table: "Messages",
            column: "MessageForUserId");

migrationBuilder.CreateIndex(
            name: "IX_Messages_MessageFromUserId",
            schema: "AppContext",
            table: "Messages",
            column: "MessageFromUserId");

migrationBuilder.AddForeignKey(
            name: "FK_Messages_AspNetUsers_MessageForUserId",
            schema: "AppContext",
            table: "Messages",
            column: "MessageForUserId",
            principalSchema: "AppContext",
            principalTable: "AspNetUsers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);

migrationBuilder.AddForeignKey(
            name: "FK_Messages_AspNetUsers_MessageFromUserId",
            schema: "AppContext",
            table: "Messages",
            column: "MessageFromUserId",
            principalSchema: "AppContext",
            principalTable: "AspNetUsers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);

还有一个 HasIndex 方法,但我不确定如何在 HasIndex 的 lambda 表达式中复制迁移产生的内容。

【问题讨论】:

    标签: c# entity-framework-core ef-fluent-api


    【解决方案1】:

    HasForeignKey() 在 EF Core 中仍然可用,就像在 EF6 中一样。误解是,它在EntityTypeBuilder&lt;T&gt; 上不可用,但在ReferenceNavigationBuilder&lt;T,K&gt; 上可用,这是WithMany() 的返回类型。

    public class PostConfiguration : IEntityTypeConfiguration<Post>
    {
        public void Configure(EntityTypeBuilder<Post> builder)
        {
            builder.HasOne(y => y.Blog)
                    .WithMany(x => x.Posts)
                    .HasForeignKey(x => x.BlogForeignKey);
        }
    }
    
    
    public class ApplicationContext :DbContext
    {
        public ApplicationContext(DbContextOptions<ApplicationContext> options) : base(options)
        {
        }
    
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
    
            builder.ApplyConfiguration(new PostConfiguration());
        }
    
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }
    
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
        public List<Post> Posts { get; set; }
    }
    
    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
    
        public int BlogForeignKey { get; set; }
        public Blog Blog { get; set; }
    }
    

    【讨论】:

    • @Marco...没有WithMany,有HasMany,但我的场景与原始迁移有点不同,至少EF如何确定它。请参阅我展示课程的帖子更新。
    • 针对您的答案尝试各种方法,但没有获得与原始代码相同的迁移代码
    • 在你的配置类中你没有指定你的关系。如果您没有在AppUserconfig 中指定您的关系,您将不会得到HasForeingKey(),还是我误解了您的问题?只需在配置类中移动 OnModelCreating 配置即可解决所有问题。
    • HasForeignKey API 在任何后续链中调用 HasManyHasOne 后可用。有多种类型具有该方法,因为不同的类型表示不同级别的关系配置。像ReferenceNavigationBuilder 是已配置单参考导航和反向导航的关系未指定/未知。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 2018-03-06
    • 2018-04-13
    相关资源
    最近更新 更多