具有活动标志的流畅映射和关系表

时间:2015-06-01 09:42:23

标签: c# entity-framework entity-framework-6

我有一个关系表,但有一个额外的列Active bit not null

我无法理解我应该如何在EF6中进行映射,我有3个表,FooBarFooBar其中FooBar是关系表

FooBar {
   FooId: int (Key and FK)
   BarId: int (Key and FK)
   Active: bit
}

Foo实体

public class Foo
{
   public int Id { get;set; }  
   public ICollection<FooBar> Bars { get; set; } 
   ...
}

FooBar实体

public class FooBar
{
   public Foo Foo { get;set; }  
   public Bar Bar { get;set; }  
   public bool Active { get;set; }
}

现在到问题,EF配置 FooBar配置

public class FooBarConfiguration : EntityTypeConfiguration<FooBar>
    {
        public FooBarConfiguration()
        {
            HasKey(fb => new[] {fb.Foo.Id, pv.Bar.Id}); //Is this correct?

            Property(pv => pv.Active);

            ToTable("ProductVehicle");
        }
    }

我不知道Foo配置应该是什么样的,所以我卡住了,试过像

这样的东西
public class FooConfiguration : EntityTypeConfiguration<Foo>
{
    public FooConfiguration()
    {
        HasKey(f => f.Id);          

        HasMany(f => f.Bars)
            .WithRequired(f => p.Foo)
            .HasForeignKey(f => f.Foo.Id);

        ToTable("Foo");
    }
}

我得到了

  

类型&#39; System.InvalidOperationException&#39;的第一次机会异常。   发生在EntityFramework.dll

中      

附加信息:属性表达式&f;&gt; f.Foo.Id&#39;   无效。表达式应代表一个属性:C#:&#39; t =&gt;   t.MyProperty&#39; VB.Net:&#39;功能(t)t.MyProperty&#39;。指定时   多个属性使用匿名类型:C#:&#39; t =&gt;新{   t.MyProperty1,t.MyProperty2}&#39; VB.Net:&#39;功能(t)新增{   t.MyProperty1,t.MyProperty2}&#39;。

我也改变了FooConfig

HasMany(f => p.Bars)
    .WithRequired(fb => fb.Foo)
    .Map(map => map.MapKey("FooId"));

我得到一点时间,现在它在FooBar配置上失败

  

类型&#39; System.InvalidOperationException&#39;的第一次机会异常。   发生在EntityFramework.dll

中      

附加信息:属性表达式&#39; fb =&gt;新[]   {fb.Foo.Id,fb.Bar.Id}&#39;无效。表达应该   表示属性:C#:&#39; t =&gt; t.MyProperty&#39; VB.Net:&#39;功能(t)   t.MyProperty&#39 ;.指定多个属性时使用匿名   类型:C#:&#39; t =&gt;新的{t.MyProperty1,t.MyProperty2}&#39; VB.Net:   &#39;功能(t)New with {t.MyProperty1,t.MyProperty2}&#39;。

编辑:我最终得到了这个解决方案,让它多了一点domaindriven,

public class ProductVehicle
{
    private Product _product;
    private Vehicle _vehicle;
    internal int ProductId { get; set; }
    internal int VehicleId { get; set; }

    public Product Product
    {
        get { return _product; }
        set
        {
            _product = value;
            ProductId = value.Id;
        }
    }

    public Vehicle Vehicle
    {
        get { return _vehicle; }
        set
        {
            _vehicle = value;
            VehicleId = value.Id;
        }
    }

    public bool Active { get; set; }
}

2 个答案:

答案 0 :(得分:2)

你需要向FooBar添加一个属性,比如说FooId:

public class FooBar
{ 
...
   public int FooId { get { return Foo.Id;}}
}

然后将代码更改为:

 HasMany(f => f.Bars)
        .WithRequired(f => p.Foo)
        .HasForeignKey(f => f.FooId);

答案 1 :(得分:1)

您尝试将导航属性的属性用作键或外键,这是不允许的。连接表本身(以及相应的实体)应该具有外键和复合主键的列(和属性)

将外键添加到连接表模型中,该模型也用作复合主键

public class FooBar
{
   public int FooId { get; set; }
   public int BarId { get; set; }

   public Foo Foo { get;set; }  
   public Bar Bar { get;set; }  
   public bool Active { get;set; }
}

将这些外键配置为主键

public class FooBarConfiguration : EntityTypeConfiguration<FooBar>
{
    public FooBarConfiguration()
    {
        HasKey(fb => new[] { fb.FooId, fb.BarId });

        // A reversed version could be placed in the Foo configuration
        // But only one is necessary
        HasRequired(fb => fb.Foo)
            .WithMany(fb => fb.Bars)
            .HasForeignKey(fb => fb.FooId);

        // Something similar for relationship with Bar

        Property(pv => pv.Active);

        ToTable("ProductVehicle"); // You mean FooBar right? ;)
    }
}