如何在EF Core 2.0中使用IEntityTypeConfiguration设置ForeignKey和Index属性

时间:2017-11-15 12:08:02

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

我正在尝试使用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表达式中复制迁移所产生的内容。

1 个答案:

答案 0 :(得分:1)

在EF Core中仍然可以使用

HasForeignKey(),就像在EF6中一样。误解是,它不在EntityTypeBuilder<T>上,而是在ReferenceNavigationBuilder<T,K>上,这是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; }
}