1

У меня проблема с плавной инфраструктурой api и entity (отношение многих ко многим). Когда я пытаюсь получить данные из базы данных, у меня есть нулевое значение на объектах Company и pkdClassification. Значение CompanyId и PkdClassyficationId правильно возвращается.Entity Framework CodeFirst от многих до многих возвращаемых объектов null

контекст

//in contrstructor set 
// this.Configuration.LazyLoadingEnabled = true; 

     .Entity<CompanyPkdClassification>() 
     (c => new { c.PkdClassyficationId, c.CompanyId }); 

     modelBuilder.Entity<Company>() 
      .HasMany(c => c.companyPkdClassification) 
      .WithRequired() 
      .HasForeignKey(c => c.CompanyId); 

     modelBuilder.Entity<PkdClassification>() 
      .HasMany(c => c.companyPkdClassification) 
      .WithRequired() 
      .HasForeignKey(c => c.PkdClassyficationId);} 

pkdClassification

public class PkdClassification 
{ 
    [Key] 
    [DisplayName("Id")] 
    public int id { get; set; } 
    ... 
    public virtual ICollection<CompanyPkdClassification> companyPkdClassification { get; set; } 
} 

companyPkdClassification

public class CompanyPkdClassification 
{ 
    [ForeignKey("company")] 
    public int CompanyId { get; set; } 

    [ForeignKey("pkdClassification")] 
    public int PkdClassyficationId { get; set; } 

    public virtual ICollection<Company> company { get; set; } 
    public virtual ICollection<PkdClassification> pkdClassification { get; set; } 
} 

и в прошлом одна компании

public class Company : baseModel 
{ 
    ... 
virtual ICollection<CompanyPkdClassification> companyPkdClassification { get; set; } 


} 

ответ

2

Лучший способ сопоставить многие-ко-многим в Code First это:

public class Classification 
{ 
    [Key] 
    [DisplayName("Id")] 
    public int id { get; set; } 
    ... 
    public virtual ICollection<Company> Companies{ get; set; } 
} 

public class Company 
{ 
    public int Id { get; set; } 
    ... 
    public virtual ICollection<Classification> Classifications { get; set; } 
} 

По умолчанию Code-First создаст третью соединяющую таблицу, ClassificationCompanies, который будет состоять рк обе таблицы т.е. ClassificationId & CompanyId.

Если вам нужно указать имя таблицы перехода и столбцы FK, то вы можете настроить отношения переопределения метода OnModelCreating от контекста частного использования Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 

    modelBuilder.Entity<Classification>() 
       .HasMany<Company>(s => s.Companies) 
       .WithMany(c => c.Classifications) 
       .Map(cs => 
         { 
          cs.MapLeftKey("ClassificationId"); 
          cs.MapRightKey("CompanyId"); 
          cs.ToTable("ClassificationCourses"); 
         }); 

} 

Другим способом создать объект, который представляет таблицу соединений (как вы пытаетесь сделать), и ставьте два отношения «один ко многим» с Classification и Company, но если вам не нужно добавлять дополнительные столбцы в таблицу соединений, рекомендуется использовать первый вариант.Если вы будете следовать этому варианту, сущность, представлять таблицу перехода будет выглядеть так:

public class CompanyPkdClassification 
{ 
    public int CompanyId { get; set; } 

    public int PkdClassyficationId { get; set; } 

    public virtual Company Company { get; set; } 
    public virtual Classification Classification { get; set; } 
} 

и конфигурации:

 modelBuilder.Entity<CompanyPkdClassification>().HasKey(c => new { c.PkdClassyficationId, c.CompanyId }); 

    modelBuilder.Entity<Company>() 
     .HasMany(c => c.companyPkdClassification) 
     .WithRequired(cc=>Company) 
     .HasForeignKey(c => c.CompanyId); 

    modelBuilder.Entity<PkdClassification>() 
     .HasMany(c => c.companyPkdClassification) 
     .WithRequired(cc=>Classification) 
     .HasForeignKey(c => c.PkdClassyficationId);} 
+0

Я выбираю второй вариант, и он отлично работает. Большое спасибо :) – michal

1

Не могли бы вы показать запрос, который вы используете, чтобы получить значение? Я думаю, что это будет связано с тем, что объекты ленивы загружены. Если вы делаете ToList() перед запросом свойства навигации, то эти значения будут равны нулю. Вы должны либо заставить значение быть включен путем добавления этого в вашем запросе:

.Include(x => x.Company) 

и так далее для каждого объекта вы хотите или запросить значение в то время как объект до сих пор живут. перед тем, как сделать ToList(); Разъяснение более подробно здесь: https://msdn.microsoft.com/en-gb/library/vstudio/bb738633%28v=vs.100%29.aspx

На основании вашего комментария ниже FirstOrDefault() выполнит запрос, поэтому после этой точки больше не будет заполняться свойства навигации. Я бы попробовал это (Предоставление dbContext.company - это набор объектов Компании):

Добавить использование для System.Data.Entity;

public Company getCompany(int id) { 
    Company data = dbContext.company.Include(x => x.companyPkdClassification .Select(y => y.company)).Include(x => x.companyPkdClassification .Select(y => y.pkdClassification)).Where(i => i.id == id).FirstOrDefault(); 
    return data; 
} 
+0

просто: 'code' общественной компании getCompany (INT идентификатор) { Данные компании = dbContext.company . Где (i => i.id == id) .FirstOrDefault(); данные о возврате; } 'code' – michal

+0

приятно, спасибо Dhunt! – DigaoParceiro

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