我正在将VS 2019与EF 6配合使用,以下是我用于开发的模型。当我尝试在EF配置中将外键“ CountryId”映射到“ Estore”模型时,我面临以下问题。
PM> EntityFrameworkCore\Enable-Migrations
两者都安装了Entity Framework Core和Entity Framework 6。实体框架核心工具正在运行。对实体框架6使用'EntityFramework6 \ Enable-Migrations'。Enable-Migrations已过时。使用添加迁移开始使用迁移。
PM> EntityFrameworkCore\Add-Migration Estore_Table
属性表达式'es => Convert(es.Address.CountryId,Object)'无效。该表达式应表示一个简单的属性访问:“ t => t.MyProperty”。指定多个属性时,请使用匿名类型:'t => new {t.MyProperty1,t.MyProperty2}'。 (参数“ propertyAccessExpression”)
请咨询。
//Country Model:-
public class Country
{
public int CountryId { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public ICollection<Estore> Estores { get; set; }
}
//Address Model:-
public class Address
{
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public int CityId { get; set; }
public string Pincode { get; set; }
public int StateId { get; set; }
public int CountryId { get; set; }
}
//Estore Model:-
public class Estore
{
public int EstoreId { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public Address Address { get; set; }
public Country Country { get; set; }
}
//Estore fields EF configuration
public class EstoreConfiguration
{
public EstoreConfiguration(EntityTypeBuilder<Estore> entityBuilder)
{
//DB Table
entityBuilder.ToTable("Estores", Constants.Database.DEFAULT_SCHEMA);
//Table Primary Key
entityBuilder.HasKey(es => es.EstoreId);
//Foriegn Key
entityBuilder.HasOne(es => es.Country).WithMany(es => es.Estores).HasForeignKey(es => es.Address.CountryId).OnDelete(DeleteBehavior.ClientSetNull);
//StateId & CityId mapping pending
//Table Fields
entityBuilder.Property(es => es.EstoreId).ValueGeneratedOnAdd().IsRequired();
entityBuilder.Property(es => es.Name).HasMaxLength(100).IsRequired();
entityBuilder.Property(es => es.Code).HasMaxLength(25).IsRequired();
//Address
entityBuilder.OwnsOne(es => es.Address, adr => { adr.Property(es => es.AddressLine1).HasColumnName("AddressLine1").HasMaxLength(50).IsRequired(); });
entityBuilder.OwnsOne(es => es.Address, adr => { adr.Property(es => es.AddressLine2).HasColumnName("AddressLine2").HasMaxLength(50); });
entityBuilder.OwnsOne(es => es.Address, adr => { adr.Property(es => es.AddressLine3).HasColumnName("AddressLine3").HasMaxLength(50); });
entityBuilder.OwnsOne(es => es.Address, adr => { adr.Property(es => es.Pincode).HasColumnName("Pincode").IsRequired(); });
entityBuilder.OwnsOne(es => es.Address, adr => { adr.Property(es => es.CityId).HasColumnName("CityId").IsRequired(); });
entityBuilder.OwnsOne(es => es.Address, adr => { adr.Property(es => es.StateId).HasColumnName("StateId").IsRequired(); });
entityBuilder.OwnsOne(es => es.Address, adr => { adr.Property(es => es.CountryId).HasColumnName("CountryId").IsRequired(); });
}
}
//Context
public class EcommerceContext : DbContext
{
public EcommerceContext()
{
}
public EcommerceContext(DbContextOptions<EcommerceContext> options) : base(options)
{
}
public DbSet<Estore> Estores { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
new EstoreConfiguration(modelBuilder.Entity<Estore>());
}
}
entityBuilder.OwnsOne(es => es.Address)
的返回类型为OwnedNavigationBuilder<Estore,Address>
。您必须使用此构建器来定义拥有类型的导航属性。
var addressBuilder = entityBuilder.OwnsOne(es => es.Address);
addressBuilder.OwnsOne(p => p.Address)
.HasOne(a => a.Country).WithMany().HasForeignKey(a => a.CountryID)
.OnDelete(DeleteBehavior.ClientSetNull);
当然,您也可以使用此addressBuidlder
设置列名,或使用this。
注意,HasOne(a => a.Country).WithMany(c => c.Estores)
是不可能的。这是因为Address
本身不是一个实体。外键CountryId
是Estore
实体的一部分,EF无法从该表中构建Address
实体。
如果您希望Country
具有地址集合和与Estore
中的引用相同的地址,则必须使Address
成为其自己的实体。