简体   繁体   English

使用流畅API的一对多实体框架

[英]Entity Framework one to many using fluent API

public class Parent
{
    public int ParentId { get; set; }
    public string Name { get; set; }
}

public class Child
{
    public int ChildId { get; set; }
    public string Name { get; set; }
    public Parent Parent { get; set; }
    public int ParentId { get; set; }
}

One parent can have many children. 一位父母可以生很多孩子。 One child can have one parent. 一个孩子可以有一个父母。 (Yeah, I know, couldn't come up with a better example.) (是的,我知道,无法提出更好的例子。)

How do you write this using the fluent API? 您如何使用流畅的API编写此代码?

Note that the Parent does not have a List<Child> Children . 请注意, Parent没有List<Child> Children That is intentional and part of the problem. 这是有意的,也是问题的一部分。

Here is a complete console application with the configuration you need: 这是具有所需配置的完整控制台应用程序:

class Program
{
    static void Main(string[] args)
    {
        var ctx = new TesteContext();
        ctx.Database.CreateIfNotExists();

        Console.ReadKey();
    }
}

public class Parent
{
    public int ParentId { get; set; }
    public string Name { get; set; }
}

public class Child
{
    public int ChildId { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public virtual Parent Parent { get; set; }
}

public class ParentConfiguration : EntityTypeConfiguration<Parent>
{
    public ParentConfiguration()
    {
        HasKey(x => x.ParentId);
    }
}

public class ChildConfiguration : EntityTypeConfiguration<Child>
{
    public ChildConfiguration()
    {
        HasKey(x => x.ChildId);

        HasRequired(x => x.Parent)
            .WithMany()
            .HasForeignKey(x => x.ParentId)
            .WillCascadeOnDelete(false);
    }
}

public class TesteContext : DbContext
{
    public DbSet<Parent> Parents { get; set; }
    public DbSet<Child> Childs { get; set; }

    public TesteContext() : base("Teste_123")
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new ParentConfiguration());
        modelBuilder.Configurations.Add(new ChildConfiguration());
    }
}

And add the connection string to you app.config : (Replacing the database, etc) 并将connection string添加到您的app.config :(替换数据库等)

<connectionStrings>
  <add name="Teste_123" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Teste_123;Integrated Security=True;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient" />
</connectionStrings>

  • With navigation property and without EntityTypeConfiguration 有导航属性,没有EntityTypeConfiguration

Just run the code: 只需运行代码:

class Program
{
    static void Main(string[] args)
    {
        var ctx = new TesteContext();
        ctx.Database.CreateIfNotExists();

        Console.ReadKey();
    }
}

public class Parent
{
    public int ParentId { get; set; }
    public string Name { get; set; }
}

public class Child
{
    public int ChildId { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public Parent Parent { get; set; }
}

public class TesteContext : DbContext
{
    public DbSet<Parent> Parents { get; set; }
    public DbSet<Child> Childs { get; set; }

    public TesteContext() : base("Teste_123")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Child>()
            .HasRequired(x => x.Parent)
            .WithMany();
    }
}

  • Without navigation property 没有导航属性

You can add a migration: 您可以添加迁移:

enable-migrations

With the code below: 使用以下代码:

public class Parent
{
    public int ParentId { get; set; }
    public string Name { get; set; }
}

public class Child
{
    public int ChildId { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
}

public class ParentConfiguration : EntityTypeConfiguration<Parent>
{
    public ParentConfiguration()
    {
        HasKey(x => x.ParentId);
    }
}

public class ChildConfiguration : EntityTypeConfiguration<Child>
{
    public ChildConfiguration()
    {
        HasKey(x => x.ChildId);
    }
}

public class TesteContext : DbContext
{
    public DbSet<Parent> Parents { get; set; }
    public DbSet<Child> Childs { get; set; }

    public TesteContext() : base("Teste_123")
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new ParentConfiguration());
        modelBuilder.Configurations.Add(new ChildConfiguration());
    }
}

If you add a migration: 如果添加迁移:

Add-Migration FirstMigration

You will get the code below: 您将获得以下代码:

public partial class FirstMigration : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.Children",
            c => new
                {
                    ChildId = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                    ParentId = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.ChildId);

        CreateTable(
            "dbo.Parents",
            c => new
                {
                    ParentId = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                })
            .PrimaryKey(t => t.ParentId);
    }

    public override void Down()
    {
        DropTable("dbo.Parents");
        DropTable("dbo.Children");
    }
}

Just add manually on the up method: 只需手动添加up方法:

AddForeignKey("dbo.Children", "ParentId", "dbo.Parents", "ParentId", cascadeDelete: false);

And you'll get: 您会得到:

public partial class FirstMigration : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.Children",
            c => new
                {
                    ChildId = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                    ParentId = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.ChildId);

        CreateTable(
            "dbo.Parents",
            c => new
                {
                    ParentId = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                })
            .PrimaryKey(t => t.ParentId);

        AddForeignKey("dbo.Children", "ParentId", "dbo.Parents", "ParentId", cascadeDelete: false);
    }

    public override void Down()
    {
        DropTable("dbo.Parents");
        DropTable("dbo.Children");
    }
}

Now, when you run update-database , you'll get what you want: 现在,当您运行update-database ,您将获得所需的内容:

在此处输入图片说明

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Child>()
            .HasRequired(c => c.Parent)
            .WithMany();
}

Here: 这里:

public partial class Parent {
    public virtual int ParentId 
    public virtual string Name
}

public class Child {
    public virtual int ChildId 
    public virtual string Name
    public virtual Parent Parent
}

and on your mappings, do: 然后在您的映射上执行以下操作:

public partial class ChildMap : ClassMap<Child> {
        public ChildMap(){
            Table("[child]");
            LazyLoad();
            Id(x => x.ChildId ).GeneratedBy.Identity().Column("ChildId ");
            Map(x => x.Name).Column("Name");
            References(x => x.Parent).Column("ParentId").Not.Nullable();
        }
    }

public partial class ParentMap : ClassMap<Parent> {
        public ParentMap(){
            Table("[parent]");
            LazyLoad();
            Id(x => x.ParentId).GeneratedBy.Identity().Column("ParentId");
            Map(x => x.Name).Column("Name");
        }
    }

This mapping is done in nhibernate, but it maps just the same as entity. 该映射是在nhibernate中完成的,但它与实体的映射相同。

Edit: Also, if you want to access all childs of one parent, you should add the List to parent entity, and map it with HasMany on the parent mapping 编辑:此外,如果要访问一个父级的所有子级,则应将List添加到父级实体,并在父级映射上使用HasMany对其进行映射

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM