Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.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
C# 如何防止EF Core将DDD ValueObject创建为表_C#_Entity Framework Core_.net 5 - Fatal编程技术网

C# 如何防止EF Core将DDD ValueObject创建为表

C# 如何防止EF Core将DDD ValueObject创建为表,c#,entity-framework-core,.net-5,C#,Entity Framework Core,.net 5,我使用的是EF Core 5.0.1 我创建了以下ValueObject public class Address : BaseValueObject { public Address(string street, string zipCode, string city, string state, string country) { Street = street; ZipCode = zipCode;

我使用的是EF Core 5.0.1

我创建了以下ValueObject

public class Address : BaseValueObject
    {

        public Address(string street, string zipCode, string city, string state, string country)
        {
            Street = street;
            ZipCode = zipCode;
            City = city;
            State = state;
            Country = country;
        }

        public string Street { get; set;  }
        public string ZipCode { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Country { get; set; }
        
        protected override IEnumerable<object> GetEqualityComponents()
        {
            yield return Street;
            yield return ZipCode;
            yield return City;
            yield return State;
            yield return Country;
        }

    }
Location对象的配置如下所示

public class LocationConfiguration : BaseEntityConfiguration<Location>
    {
        public override void Configure(EntityTypeBuilder<Location> builder)
        {            
            builder.OwnsOne(o => o.Address, a =>
            {
                a.Property(p => p.Street).HasMaxLength(600)
                    .HasDefaultValue("");
                a.Property(p => p.City).HasMaxLength(150)
                    .HasDefaultValue("");
                a.Property(p => p.State).HasMaxLength(60)
                    .HasDefaultValue("");
                a.Property(p => p.ZipCode).HasMaxLength(12)
                    .HasDefaultValue("");
            });

            base.Configure(builder);
        }
    }
公共类位置配置:BaseEntityConfiguration
{
公共覆盖无效配置(EntityTypeBuilder)
{            
builder.OwnsOne(o=>o.Address,a=>
{
a、 属性(p=>p.Street)。HasMaxLength(600)
.HasDefaultValue(“”);
a、 属性(p=>p.City).HasMaxLength(150)
.HasDefaultValue(“”);
a、 属性(p=>p.State).HasMaxLength(60)
.HasDefaultValue(“”);
a、 属性(p=>p.ZipCode).HasMaxLength(12)
.HasDefaultValue(“”);
});
配置(生成器);
}
}
问题是EF Core迁移仍在将ValueObject创建为数据库中的表。 我做错了什么? 在生成的迁移代码中,我可以看到以下内容:

migrationBuilder.CreateTable(
                name: "Location",
                columns: table => new
                {
                    Id = table.Column<long>(type: "INTEGER", nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    Name = table.Column<string>(type: "TEXT", maxLength: 80, nullable: false),
                    Timestamp = table.Column<string>(type: "TEXT", rowVersion: true, nullable: false, defaultValueSql: "CURRENT_TIMESTAMP")
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Location", x => x.Id);
                });



migrationBuilder.CreateTable(
                name: "Address",
                columns: table => new
                {
                    LocationId = table.Column<long>(type: "INTEGER", nullable: false),
                    Street = table.Column<string>(type: "TEXT", maxLength: 600, nullable: true, defaultValue: ""),
                    ZipCode = table.Column<string>(type: "TEXT", maxLength: 12, nullable: true, defaultValue: ""),
                    City = table.Column<string>(type: "TEXT", maxLength: 150, nullable: true, defaultValue: ""),
                    State = table.Column<string>(type: "TEXT", maxLength: 60, nullable: true, defaultValue: ""),
                    Country = table.Column<string>(type: "TEXT", nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Address", x => x.LocationId);
                    table.ForeignKey(
                        name: "FK_Address_Location_LocationId",
                        column: x => x.LocationId,
                        principalTable: "Location",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                });
migrationBuilder.CreateTable(
名称:“地点”,
列:表=>new
{
Id=table.Column(类型:“INTEGER”,可为空:false)
.Annotation(“Sqlite:Autoincrement”,true),
Name=table.Column(类型:“TEXT”,最大长度:80,可空值:false),
Timestamp=table.Column(类型:“TEXT”,行版本:true,可空:false,defaultValueSql:“当前_时间戳”)
},
约束:表=>
{
表.PrimaryKey(“PK_位置”,x=>x.Id);
});
migrationBuilder.CreateTable(
姓名:“地址”,
列:表=>new
{
LocationId=table.Column(类型:“INTEGER”,可为空:false),
Street=table.Column(类型:“TEXT”,最大长度:600,可空值:true,默认值:),
ZipCode=table.Column(类型:“TEXT”,maxLength:12,可空:true,defaultValue:),
City=table.Column(类型:“TEXT”,最大长度:150,可空值:true,默认值:),
State=table.Column(类型:“TEXT”,maxLength:60,可空:true,defaultValue:),
Country=表列(类型:“TEXT”,可为空:true)
},
约束:表=>
{
表.PrimaryKey(“PK_地址”,x=>x.LocationId);
表1.外键(
名称:“FK\U地址\U位置\U位置ID”,
列:x=>x.LocationId,
原则:“位置”,
主栏:“Id”,
onDelete:引用。级联);
});
最后是DBContext类

public class MyDbContext : DbContext
    {        
        public PlannerDbContext(DbContextOptions<PlannerDbContext> options)
            : base(options)
        {
        }                     
        
        public DbSet<Location> Locations { get; set; }        


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {            
            // do not use plural form for table names
            modelBuilder.Model.GetEntityTypes()
                .Configure(e => e.SetTableName(e.DisplayName())); 
                            
            base.OnModelCreating(modelBuilder);                                              

            modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());            
        }
    }
公共类MyDbContext:DbContext
{        
public PlannerDbContext(DbContextOptions选项)
:基本(选项)
{
}                     
公共数据库集位置{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{            
//表名不要使用复数形式
modelBuilder.Model.GetEntityTypes()
.Configure(e=>e.SetTableName(e.DisplayName());
基于模型创建(modelBuilder);
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.getExecutionGassembly());
}
}

EF为值对象创建表的原因是代码中更改了表命名约定的部分。我想,我是从一些关于热的问题中复制过来的,以单数形式设置表名

此方法
modelBuilder.Model.GetEntityTypes()
将枚举数返回给模型中的所有对象(包括值对象)。针对值对象配置表名属性将导致EF将此类型视为实体

这部分

            // do not use plural form for table names
            modelBuilder.Model.GetEntityTypes()
                .Configure(e => e.SetTableName(e.DisplayName())); 
应改为

            // do not use plural form for table names
            modelBuilder.Model.GetEntityTypes()
                .Where(x => !x.ClrType.IsSubclassOf(typeof(BaseValueObject)))
                .Configure(e => e.SetTableName(e.DisplayName()));

我觉得一切都很好。唯一奇怪的是Address实体上的无参数私有构造函数。如果删除它,会得到相同的结果吗?而且,这并不是说它会有什么不同,静态Create方法返回的是一个结果,而不仅仅是地址。在dbcontext中的OnModelCreating中使用fluentapi如何:
modelBuilder.Entity().OwnsOne(c=>c.Address,a=>{/…})
并在您的上下文中,删除code
公共数据库集地址{get;set;}
@Yinqiu DbContext类中没有数据库集地址{get;set;}。在dbcontext中的OnModelCreating中设置配置不会改变任何内容
            // do not use plural form for table names
            modelBuilder.Model.GetEntityTypes()
                .Where(x => !x.ClrType.IsSubclassOf(typeof(BaseValueObject)))
                .Configure(e => e.SetTableName(e.DisplayName()));