如何设置Entity Framework以将两个类映射到同一个表

时间:2013-08-07 12:49:41

标签: entity-framework-5

我和EF5一直笨手笨脚但似乎无法将两个域类映射到单个数据库表。

我得到的错误是:

   Message: "The type 'Basd.Erp.Wms.Purchasing.SupplierProfile' has already been configured as an entity type. It cannot be reconfigured as a complex type."

这是我的DbContext:

    public class PurchasingContext : DisconnectedEntityContext
    {
        public DbSet<SupplierCard> Suppliers { get; set; }
        public DbSet<PurchaseCategory> PurchaseCategories { get; set; }

        public PurchasingContext() : this("Basd.Erp.Wms") { }

        public PurchasingContext(string connectionStringName) : base(connectionStringName) { }

        public static PurchasingContext GetInstance(EfDataProvider provider) { return new PurchasingContext(provider.ConnectionStringName); }
    }
}

这些是我的课程:

namespace Basd.Erp.Wms.Purchasing
{

    public class SupplierCard : ContactCard, ISupplierCard
    {
        private ICollection<PurchaseCategory> _purchaseCategories;

        public ICollection<PurchaseCategory> PurchaseCategories
        {
            get { return _purchaseCategories; }
            set { SetNotifyField(ref _purchaseCategories, value, () => PurchaseCategories); }
        }

        public SupplierProfile Profile { get; protected set; }

        private SupplierCard()
        {
            this.Profile = new SupplierProfile();
            this.PurchaseCategories = new Collection<PurchaseCategory>();
        }

        public SupplierCard(long id, string alf, string name)
            : this(id, alf, new SimpleNameHolder(name), new Collection<IPhysicalAddress>(), new DigitalAddresses()) { }

        public SupplierCard(long id, string alf, INameHolder nameHolder,
                            ICollection<IPhysicalAddress> physicalAddresses, IDigitalAddresses digitalAddresses)
            : this(id, alf, nameHolder, physicalAddresses, digitalAddresses, null) { }

        public SupplierCard(long id, string alf, INameHolder nameHolder,
           ICollection<IPhysicalAddress> physicalAddresses, IDigitalAddresses digitalAddresses, IValidatableObject validator)
            : base(id, alf, nameHolder, physicalAddresses, digitalAddresses, validator)
        {
            this.Profile = new SupplierProfile();
            this.PurchaseCategories = new Collection<PurchaseCategory>();
        }
    }
}

  public class SupplierProfile : AbstractAspect
    {


        private TradingEntity _incType;

        public TradingEntity BusinessType
        {
            get { return _incType; }
            set
            {
                if (_incType != null) { this.DeregisterSubPropertyForChangeTracking(this.BusinessType); }
                _incType = value; this.OnPropertyChanged("TradingType");
                this.RegisterSubPropertyForChangeTracking(this.BusinessType);
            }
        }

        private bool _emailOk;
        private bool _smailOk;

        public bool MarketingEmailOk
        {
            get { return _emailOk; }
            set { _emailOk = value; this.OnPropertyChanged("MarketingEmailOk"); }
        }


        public bool MarketingSmailOk
        {
            get { return _smailOk; }
            set { _smailOk = value; this.OnPropertyChanged("MarketingSmailOk"); }
        }

        public SupplierProfile()
            : base()
        {
            this.BusinessType = new TradingEntity(ContactLegalType.Limited);
        }
    }
}

这些是我的配置类:

 [Export(typeof(IEntityConfiguration))]
    public class SupplierCardConfiguration
        : EntityTypeConfiguration<SupplierCard>, IEntityConfiguration
    {

        public SupplierCardConfiguration()
        {
            this.ToTable("SupplierCard", "erp_wms");
            HasKey(u => u.Id);
            Property(u => u.Id).HasColumnName("SupplierId");
            Ignore(u => u.UsePropertyNotifications);
            Property(u => u.Profile.MarketingEmailOk).HasColumnName("MarketingEmailOk");
            HasMany(i => i.PurchaseCategories)
                .WithMany(c => c.Suppliers)
                .Map(mc =>
                {
                    mc.MapLeftKey("CategoryId");
                    mc.MapRightKey("SupplierId");
                    mc.ToTable("SupplierPurchaseCategory", "erp_wms");
                });
        }


        public void AddConfiguration(ConfigurationRegistrar registrar)
        {
            registrar.Add(this);
        }
    }

 [Export(typeof(IEntityConfiguration))]
    public class SupplierProfileConfiguration
        : EntityTypeConfiguration<SupplierProfile>, IEntityConfiguration
    {

        public SupplierProfileConfiguration()
        {
            this.ToTable("SupplierCard", "erp_wms");
            Ignore(u => u.UsePropertyNotifications);
            Property(u => u.MarketingEmailOk).HasColumnName("MarketingEmailOk");
        }


        public void AddConfiguration(ConfigurationRegistrar registrar)
        {
            registrar.Add(this);
        }
    }

更新

好的,我已经尝试忽略SupplierProfile,因为建议没有改变任何东西。然后我尝试删除供应商档案的配置类并离开

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Ignore<SupplierProfile>();
        base.OnModelCreating(modelBuilder);
    }

并产生错误:

  

{“属性'Profile'不是类型的声明属性   'SupplierCard'。验证该属性尚未明确   通过使用Ignore方法或从模型中排除   NotMappedAttribute数据注释。确保它是有效的   原始财产。“}       [System.InvalidOperationException]:{“属性'Profile'不是'SupplierCard'类型的声明属性。验证是   尚未使用该属性明确地从模型中排除属性   忽略方法或NotMappedAttribute数据注释。确保它   是一个有效的原始属性。“}

然后我尝试删除

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Ignore<SupplierProfile>();
        base.OnModelCreating(modelBuilder);
    }

同时省略了SupplierProfile的配置类,并产生错误:

  

消息:“列名无效   'Profile_BusinessType_ContactLegalType'。\ r \ n无效的列名   'Profile_BusinessType_TradingSince'。\ r \ n无效的列名   'Profile_BusinessType_State'。\ r \ n无效的列名   'Profile_BusinessType_UsePropertyNotifications'。\ r \ n无效列   name“MarketingEmailOk”。\ r \ n无效的列名   'Profile_MarketingSmailOk'。\ r \ n无效的列名   'Profile_State'。\ r \ n无效的列名   'Profile_UsePropertyNotifications'。\ r \ n无效的列名   'OwnerId'。\ r \ n无效的列名称'State'。“

就像我说的那样, ** bumbling ** 沿着;)

2 个答案:

答案 0 :(得分:0)

阅读this后,我认为这可能与您在SupplierCard课程中的关系有关。

public class SupplierCard : ContactCard, ISupplierCard
{
  public SupplierProfile Profile { get; protected set; }
}

我猜测它在映射SupplierCard时注册为复杂类型。 建议的解决方法是忽略它。

modelBuilder.Ignore<SupplierProfile>();

我自己从未遇到过这个问题,所以不确定这是否有帮助。

答案 1 :(得分:0)

所以经过大量的讨论后发现底层问题是实体框架5中的一个错误。这个错误已在EF6 beta中修复。所有其他错误实际上只是掩盖了这个潜在的错误。

以下解释并不是非常好,因为我自己并不完全理解。 简短的回答是:使用EF6或以其他方式修改EF5源代码。

事实证明,如果你在程序集B中有一个类,它具有在程序集A中定义的枚举类型的属性,则EF5会混淆并认为枚举已丢失或以某种方式不可用,并设置有关尝试生成类型本身

所以我有:

  • 装配A包含枚举类型AA。
  • 程序集B引用程序集A,因此包含的类BB可以具有AA类型的属性。
  • 参考A和A组件的EF5数据层组件。乙
  • EF5配置层程序集引用程序集A和乙

它失败了。

但是,如果我“简单地”将枚举类型AA移动到程序集B中,那么一切正常。 这当然是完全没用的,因为我为任何有成员需要枚举AA的程序集在程序集B上设置了各种依赖。但那是考验。

最重要的是,由于订单程序集在运行时加载,因此似乎还有一些特殊情况,其中我刚才所说的所有内容都不适用。这种加载的顺序不能被强制,即它是非决定性的,所以它是运气好的。