2014-11-21 12 views
5

Bu soruda: Ef Many To Many, bir bağlantı tablosunun manuel olarak nasıl belirtileceğine dair bir cevap geldi. Ama biraz kendine özgü bir durumum var (ki eminim ki gerçekten eşsiz değil).EF Akıcı API Çok sayıda farklı ID Alan Adına Birçok Kişi Adları

İki tablomun her birinde bir Kimlik alanı var. E.G .: [dbo].[Account].[Id] ve [dbo].[Person].[Id]. Benim Kod-Birinci, bu tablolardan her biri aşağıdaki OnModelCreating sahiptir:

modelBuilder.Entity<Account>.HasKey(x => x.Id); 
modelBuilder.Entity<Person>.HasKey(x => x.Id); 

Ama [dbo].[AccountsToPersons]... tablo AccountsToPersons tablo kodunda bir sınıf tarafından temsil edilmediği [AccountId] ve [PersonId]

alanları ör .: vardır.

Açıkçası halihazırda var olan bir Modelim var, ancak modeli veritabanından güncellemek yerine EF Code-First Fluent API kullanıyoruz.

Farklı kimlik sütunları adlarını eşleme ile çalışmasını sağlamak için bu kodu nasıl değiştirebilirim? EF Query (from x in context.Accounts select x).ToList(); için temel bir Linq çalıştırırken

public DbSet<Person> Persons { get; set; } 
public DbSet<Account> Accounts { get; set; } 
. . . 
modelBuilder.Entity<Account>() 
    .HasMany(a => a.Persons) 
    .WithMany() 
    .Map(x => 
    { 
    x.MapLeftKey("AccountId"); // <-- Account.Id to AccountsToPersons.AccountId?? 
    x.MapRightKey("PersonId"); // <-- Person.Id to AccountsToPersons.PersonId?? 
    x.ToTable("AccountsToPersons"); 
    }); 

, sorgu aşağıdaki hata nedeniyle başarısız: "Geçersiz Sütun Adı 'Person_Id'"

Ancak Sorgu (from x in context.Persons select x).ToList();'u çalıştırırken, hata alıyorum. Temel Yazılan sütunların dışında

, benim modeller bunlar onlara ekledi:

// In my Account Model, I also have this property: 
public IList<Person> Persons { get; set; } 

// In my Person Model, I also have this property: 
public IList<Account> Accounts { get; set; } // <-- in the Person model 

Ve rağmen Hesaplarımın sorgu geçer ve saha bilgisini olsa bile, Persons alan her zaman boş olduğuna dikkat edin ben Eminim benim AccountsToPersons tablosumda bağlantılar var.

+1

Bu standart EF adlandırma con gibi görünüyor temel anlaşma-. Bunu denedin mi? Çalışıyor mu?'Hesap' ve 'Kişi' neye benziyor? – Jasen

+0

@Jasen İlk başta çalıştığımı düşündüm, ancak testim sadece modeli yaratırken. İlk LINQ'umu çalıştırdım ve yukarıdaki ek bilgilerle başarısız oldu. – Suamere

+0

Varolan birleştirme tablonuzun _AccountId_ ve _PersonId_ sütunları varsa, bu akıcı eşleme doğru görünüyor. Hata başka bir yerde yatar. – Jasen

cevap

4

deneyin sizin WithMany maddeye p => p.Accounts ekleyerek:

modelBuilder.Entity<Account>() 
    .HasMany(a => a.Persons) 
    .WithMany(p => p.Accounts) // <-- I think this should fix it 
    .Map(x => 
    { 
    x.MapLeftKey("AccountId"); // <-- Account.Id to AccountsToPersons.AccountId?? 
    x.MapRightKey("PersonId"); // <-- Person.Id to AccountsToPersons.PersonId?? 
    x.ToTable("AccountsToPersons"); 
    }); 
+0

> gitmeye çalıştığınız kullanımı görebiliyorum. Suamere

+0

benim için bile onsuz çalışıyor, garip? – alexo

+0

@Suamere bu gönderiye göz atın: http://stackoverflow.com/questions/5927272/ef-code-first-withmany – SOfanatic

2

Sorununuz için bir test çözümü oluşturdum ve bana göre çalışıyor. i benden daha farklı görmediniz

Bir şey şudur:

public IList<Person> Persons { get; set; } // <-- in the Account model 
public IList<Account> Accounts { get; set; } // <-- in the Person model 

bu işe değiştirerek deneyin:

public DbSet<Person> Persons { get; set; } 
public DbSet<Account> Accounts { get; set; } 

bu I`ll benim tüm kurulum sonrası işe yaramazsa.

Benim yapısı böyle bakar ve görüntülenen sorguları için çalışır:

public class Person 
{ 
    public int ID { get; set; } 

    public string Name { get; set; } 

    public IList<Account> Accounts { get; set; } 
} 

public class Account 
{ 
    public int ID { get; set; } 

    public string Name { get; set; } 

    public IList<Person> Persons { get; set; } 
} 

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    public DbSet<Account> AccountSet { get; set; } 

    public DbSet<Person> PersonSet { get; set; } 

    public ApplicationDbContext() 
     : base("DefaultConnection") 
    { 
     this.Database.Log = (msg) => { Debug.Write(msg); }; 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 

     modelBuilder.Entity<Account>().HasKey(x => x.ID); 
     modelBuilder.Entity<Person>().HasKey(x => x.ID); 

     modelBuilder.Entity<Account>() 
      .HasMany(a => a.Persons) 
      .WithMany() 
      .Map(w => 
      { 
       w.MapLeftKey("AccountId"); 
       w.MapRightKey("PersonId"); 
       w.ToTable("AccountsToPersons"); 
      }); 
    } 
} 
+0

Modelimi çoğaltmak için zaman ayırdığınız için teşekkür ederiz. Bununla birlikte, kalıcı bir cahil model projemiz var ve DbSet için Entity Framework ekleyerek tablodan çıkıyoruz. Yine de işe yarayıp yaramadığını görmek için birkaç dakikanızı ayıracağım ama umarım şu anda kurduğumuz ilkelerimizi kırmaya zorlamayan bir cevap vardır. – Suamere

+0

Varlık Çerçevem, DbSet'i kullanmama izin vermiyor. Nedenini araştırırken, [Bu Soru] 'nun (http://stackoverflow.com/questions/14351690/ef5-code-first-error-cannot-be-inferred-from-the-usage) EF'nin ICollection'a erişmesi gerektiğini belirttiğini buldum Veri kümeleriyle çalışmak için arabirimin Add() işlevselliği. Ama sizden daha fazla bilgi sırayla olabilir. – Suamere

+0

bir şey eksik olabilir DbSet desteklemiyor nedeni olabilir? Ve evet, ICollection navigasyon özellikleri içindir, bunlar kısmi olarak da işaretlenmiştir, çünkü EF sizin için yeni bir sınıf oluşturuyor ve sanal olarak göründüğü her şeyi taşıyor. Bu durumda ICollection özellikleri – alexo

0

Eğer hafifçe AccountsToPersons eşleme değiştirmeyi denediniz:

modelBuilder.Entity<Account>() 
    .HasMany(a => a.Persons) 
    .WithMany(p => p.Accounts) <-- Change 
    .Map(x => 
    { 
     x.MapLeftKey("AccountId"); // <-- Account.Id to AccountsToPersons.AccountId?? 
     x.MapRightKey("PersonId"); // <-- Person.Id to AccountsToPersons.PersonId?? 
     x.ToTable("AccountsToPersons"); 
    }); 
İlgili konular