【问题标题】:EntityFrameworkCore - When specifying multiple propertiesEntityFrameworkCore - 指定多个属性时
【发布时间】:2020-05-19 18:41:54
【问题描述】:

我正在使用带有 EF 6 的 VS 2019,以下是我用于开发的模型。当我尝试在 EF 配置中将外键“CountryId”映射到“Estore”模型时,我遇到了以下问题。

PM> EntityFrameworkCore\Enable-Migrations

Entity Framework Core 和 Entity Framework 6 都已安装。 Entity Framework Core 工具正在运行。对实体框架 6 使用“EntityFramework6\Enable-Migrations”。 Enable-Migrations 已过时。使用 Add-Migration 开始使用迁移。

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.HasOne(es => es.Country).WithMany(es => es.Estores).HasForeignKey(es => es.Address.CountryId) .OnDelete(DeleteBehavior.ClientSetNull);

标签: entity-framework-core


【解决方案1】:

entityBuilder.OwnsOne(es =&gt; es.Address) 的返回类型是OwnedNavigationBuilder&lt;Estore,Address&gt;。您必须使用此构建器来定义所拥有类型的导航属性。

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 =&gt; a.Country).WithMany(c =&gt; c.Estores) 是不可能的。这是因为Address 本身并不是一个实体。外键 CountryIdEstore 实体的一部分,EF 无法从该表中构建 Address 实体。

如果您希望Country 拥有一组地址并且Estore 中的引用地址相同,那么您必须使Address 成为它自己的实体。

【讨论】:

    猜你喜欢
    • 2018-11-01
    • 2020-05-13
    • 2017-11-30
    • 2012-09-02
    • 1970-01-01
    • 2013-09-20
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多