Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 实体框架核心所有者可以创建单独的表,而不是像预期的那样向同一个表添加属性_Entity Framework_Core_Entity Framework Migrations_Ef Core 2.1_Owned Types - Fatal编程技术网

Entity framework 实体框架核心所有者可以创建单独的表,而不是像预期的那样向同一个表添加属性

Entity framework 实体框架核心所有者可以创建单独的表,而不是像预期的那样向同一个表添加属性,entity-framework,core,entity-framework-migrations,ef-core-2.1,owned-types,Entity Framework,Core,Entity Framework Migrations,Ef Core 2.1,Owned Types,我认为EntityFramework核心拥有的类型默认情况下会添加到与其所有者相同的表中。但我没有在迁移中看到这一点 有人能告诉我这里的情况吗 有没有一种方法可以通过直接将Name属性添加到Person表中来获得所需的迁移 public class Person { public Name Name { get; set; } } public class Name { public string FirstName { get; set; } public strin

我认为EntityFramework核心拥有的类型默认情况下会添加到与其所有者相同的表中。但我没有在迁移中看到这一点

有人能告诉我这里的情况吗

有没有一种方法可以通过直接将Name属性添加到Person表中来获得所需的迁移

public class Person
{
    public Name Name { get; set; }
}

public class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PersonConfiguration : IEntityTypeConfiguration<Person>
{
    public void Configure(EntityTypeBuilder<Person> person)
    {
          person.OwnsOne(p => p.Name);
    }
}
公共类人物
{
公共名称名称{get;set;}
}
公共类名
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
公共类人员配置:IEntityTypeConfiguration
{
公共void配置(EntityTypeBuilder人员)
{
person.OwnsOne(p=>p.Name);
}
}
dotnet ef迁移添加没有预见到这一点 导致

public partial class DidNotSeeThatComing : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Name",
            columns: table => new
            {
                FirstName = table.Column<string>(type: "varchar", nullable: true),
                LastName = table.Column<string>(type: "varchar", nullable: true),
                PersonId = table.Column<Guid>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Name", x => x.PersonId);
                table.ForeignKey(
                    name: "FK_Name_Person_PersonId",
                    column: x => x.PersonId,
                    principalTable: "Person",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });
        );
    }
}
public分部类没有看到即将到来的消息:迁移
{
受保护的覆盖作废(MigrationBuilder MigrationBuilder)
{
migrationBuilder.CreateTable(
姓名:“姓名”,
列:表=>new
{
FirstName=table.Column(类型:“varchar”,可为空:true),
LastName=table.Column(类型:“varchar”,可为空:true),
PersonId=table.Column(可空:false)
},
约束:表=>
{
表.PrimaryKey(“PK_Name”,x=>x.PersonId);
表1.外键(
姓名:“FK\u姓名\u人名\u人名”,
列:x=>x.PersonId,
原则性:“人”,
主栏:“Id”,
onDelete:引用。级联);
});
);
}
}

我自己用这个配置代码无意中创建了这个

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);
   foreach (var entity in modelBuilder.Model.GetEntityTypes())
   {
       entity.Relational().TableName = entity.Name;
   }
}
这是我正在使用的解决方法

[Owned] // Microsoft.EntityFrameworkCore
public class Name { ... }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);
   foreach (var entity in modelBuilder.Model.GetEntityTypes())
   {
       if(!entity.ClrType.GetCustomAttributes().OfType<OwnedAttribute>().Any())
       {
            entity.Relational().TableName = entity.Name;
       }
   }
}    
[Owned]//Microsoft.EntityFrameworkCore
公共类名{…}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
foreach(modelBuilder.Model.GetEntityTypes()中的var实体)
{
如果(!entity.ClrType.GetCustomAttributes().OfType().Any())
{
entity.Relational().TableName=entity.Name;
}
}
}    

尝试以下方法:

public class Person
{
    public Guid Id { get; set; }
    public Name Name { get; set; }
}

public class Name
{
    public Guid Id { get; set; }
    public Guid PersonId {get;set;}
    public Person Person { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PersonConfiguration : IEntityTypeConfiguration<Person>
{
    public void Configure(EntityTypeBuilder<Person> person)
    {
        person.OwnsOne(p => p.Name,
            nCls =>
            {
                nCls.HasOne(n => n.Person);
                nCls.HasKey(n => new {n.Id, n.PersonId});
                nCls.HasForeignKey(m => m.PersonId);
                nCls.ToTable(nCls.OwnedEntityType.ClrType.Name);
            }
        );
    }
}
公共类人物
{
公共Guid Id{get;set;}
公共名称名称{get;set;}
}
公共类名
{
公共Guid Id{get;set;}
公共Guid PersonId{get;set;}
公众人物{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
公共类人员配置:IEntityTypeConfiguration
{
公共void配置(EntityTypeBuilder人员)
{
person.OwnsOne(p=>p.Name,
nCls=>
{
nCls.HasOne(n=>n人);
nCls.HasKey(n=>new{n.Id,n.PersonId});
nCls.HasForeignKey(m=>m.PersonId);
ntable(nCls.OwnedEntityType.ClrType.Name);
}
);
}
}
这应该会让您得到如下结果:

protected override void Up(MigrationBuilder migrationBuilder)
{
// the table names are lower case because my convention is to generate all names in snake_case

    migrationBuilder.CreateTable(
        name: "persons",
        columns: table => new
        {
            id = table.Column<Guid>(nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("pk_persons", x => x.id);
        });

    migrationBuilder.CreateTable(
        name: "name",
        columns: table => new
        {
            id = table.Column<Guid>(nullable: false),
            person_id = table.Column<Guid>(nullable: false),
            first_name = table.Column<string>(maxLength: 256, nullable: true),
            last_name = table.Column<string>(maxLength: 256, nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("pk_name", x => new { x.id, x.person_id });
            table.ForeignKey(
                name: "fk_name_persons_person_id",
                column: x => x.person_id,
                principalTable: "persons",
                principalColumn: "id",
                onDelete: ReferentialAction.Cascade);
        });
}
protected override void Up(MigrationBuilder MigrationBuilder)
{
//表名是小写的,因为我的约定是生成所有大小写的名称
migrationBuilder.CreateTable(
姓名:“人”,
列:表=>new
{
id=table.Column(可空:false)
},
约束:表=>
{
表.PrimaryKey(“pk_persons”,x=>x.id);
});
migrationBuilder.CreateTable(
姓名:“姓名”,
列:表=>new
{
id=table.Column(可空:false),
person_id=table.Column(可空:false),
first_name=table.Column(maxLength:256,nullable:true),
last_name=table.Column(maxLength:256,null:true)
},
约束:表=>
{
表.PrimaryKey(“pk_name”,x=>new{x.id,x.person_id});
表1.外键(
姓名:“fk\U姓名\U人员\U人员id”,
列:x=>x.person\u id,
原则性:“人”,
主栏:“id”,
onDelete:引用。级联);
});
}

@Davious我今天遇到了完全相同的问题,感谢您分享您的解决方案。这里是我的解决方案,您不需要
OwnedAttribute
,因为您还可以使用
entity.isoowned()
。我总是尝试通过DbContext进行所有验证

///[Owned] // Not needed anymore
public class Name { ... }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);
   modelbuilder.Entity<Person>().OwnsOne(p => p.Name)

   foreach (var entity in modelBuilder.Model.GetEntityTypes())
   {
       if(!entity.IsOwned())
       {
            entity.Relational().TableName = entity.Name;
       }
   }
}  

//[Owned]//不再需要了
公共类名{…}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
modelbuilder.Entity().OwnsOne(p=>p.Name)
foreach(modelBuilder.Model.GetEntityTypes()中的var实体)
{
如果(!entity.IsOwned())
{
entity.Relational().TableName=entity.Name;
}
}
}  

您的想法是正确的-默认情况下,它与所有者放在同一张表中,我无法重现该问题。你有干净的回购项目吗?@IvanStoev验证了一个干净的回购项目的预期效果,在发生这种情况的项目中有任何不寻常的代码吗?像模型实体/反射上的循环和调用
ToTable
?Ugg我用foreach(modelBuilder.model.GetEntityTypes()中的var实体){entity.Relational(),所以在最后,它是不寻常的模型实体循环:)很高兴你已经解决了这个问题。