2

Я хочу добиться:Прямая навигацию в Entity Framework 6

public class A 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<B> Bs { get; set; } 
} 

public class B 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<A> As { get; set; } 
} 

public class C 
{ 
    public int AID { get; set; } 
    public int BID { get; set; } 
    public string OtherProperty { get; set; } 
} 

А и В много много, к которым присоединились C. Однако, C также имеет некоторые из его собственных свойств, поэтому я необходимо представить его.

Я хочу перейти от A непосредственно к Bs, не пропуская сначала C. (и от B до As)

Это было бы легко, если бы C просто присоединился к A и B без дополнительных свойств. Но поскольку C имеет дополнительные свойства, и мне нужно его представлять, я получаю следующую ошибку.

Невозможно автоматически привязать свойство навигации «Bs» к типу сущности «A» для набора объектов или одноэлементного «A», потому что есть два или более подходящих набора сущностей или одноточечных объектов. Соответствующие сущности или одиночные единицы: B, Bs.

Вот мое отображение помогает ...

modelBuilder.Entity<A>() 
       .HasMany<B>(x => x.Bs) 
       .WithMany(x => x.As) 
       .Map(x => 
        { 
         x.MapLeftKey("a_id"); 
         x.MapRightKey("b_id"); 
         x.ToTable("c"); 
        }); 
+0

Можете ли вы написать пользовательские 'CConfiguration: EntityTypeConfiguration '? – abatishchev

+0

@abatishchev Я не знаком, не могли бы вы объяснить? – hatcyl

+0

См. Http://www.remondo.net/code-first-fluent-api-entity-type-configuration/, http://www.entityframeworktutorial.net/code-first/entitytypeconfiguration-class.aspx и т. Д. – abatishchev

ответ

0

Если вы хотите работать с C, я предлагаю вам изменить свою модель, как я покажу ниже:

public class A 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<C> Cs { get; set; } 
} 

public class B 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<C> Cs { get; set; } 
} 

public class C 
{ 
    public int AID { get; set; } 
    public virtual A A { get; set; }  
    public int BID { get; set; } 
    public virtual B B { get; set; } 

    public string OtherProperty { get; set; } 
} 

Тогда , в вашем методе OnModelCreating вы можете настроить два отношения «один ко многим» между C и A и C и B следующим образом:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<C>().HasRequired(c => c.A).WithMany(a => a.Cs).HasForeignKey(c => c.AID); 
    modelBuilder.Entity<C>().HasRequired(c => c.B).WithMany(b => b.Cs).HasForeignKey(c => c.BID); 
} 

Как вы можете видеть, это в конце концов многие-ко-многим, но теперь вы отображения таблицы перехода тоже, потому что вы должны добавить некоторые свойства на нем.

+0

благодарю вас за ответ, я знаю, что могу пройти через C, но я хотел специально пропустить его. – hatcyl

+0

Извините, но я боюсь, что это невозможно. Если вы добавляете новый столбец в таблицу соединений, вам нужен новый объект вместо прямого отношения многих ко многим, чтобы иметь доступ к новому столбцу. – octavioccl

0

Entity Framework будет абстрагировать таблицу соединений «много-ко-многим», если вы ее не определили. Поскольку вы хотите добавить свойство в эту таблицу соединений, вам (конечно) нужно определить эту таблицу. В этот момент вам нужно пройти таблицу соединений, чтобы получить B s от A и A s от B.

Кроме того, если вы используете навигационные свойства в C, вам даже не нужно определить отношения с Fluent API ...

public class A 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<C> Cs { get; set; } 
} 

public class B 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<C> Cs { get; set; } 
} 

public class C 
{ 
    public int ID { get; set; } 
    public virtual A A { get; set; } 
    public virtual B B { get; set; } 
    public string OtherProperty { get; set; } 
} 

И если вы хотите, чтобы обеспечить уникальность ...

public class C { 
    [Key, Column(Order = 0)] 
    public int AID { get; set; } 
    [ForeignKey("AID")] 
    public virtual A A { get; set; } 

    [Key, Column(Order = 1)] 
    public int BID { get; set; } 
    [ForeignKey("BID")] 
    public virtual B B { get; set; } 

    public string OtherProperty { get; set; } 
} 
+0

спасибо за ответ, я знаю, что могу пройти через C, но я хотел специально пропустить его. – hatcyl

+0

Как вы думаете, что это может сработать? Единственный способ «пропустить» таблицу - абстрагировать ее на уровне ORM, чтобы вы не видели ее в коде. По сути, вы не можете получить доступ к скрытой таблице на уровне ORM. –

Смежные вопросы