2015-08-12 1 views
2

Мы используем Entity Framework 6, код первого, чтобы сохранить сложное дерево объектов, которые выглядят следующим образом:Entity Framework код первого многие-ко-многим не работает

public abstract class DataCode 
{ 
    public long Id { get; set; } 
    public string Code { get; set; } 
    public string Description { get; set; } 
    public bool IsActive { get; set; } 
} 

public class InternCode : DataCode 
{ 
    public string PrimaryRelationalOperator { get; set; } 
    public string PrimaryValue { get; set; } 
    public string SecondaryRelationalOperator { get; set; } 
    public string SecondaryValue { get; set; } 
} 

public class Model : DataCode 
{ 
    public ICollection<string> Aliases { get; set; } 
    public bool ExportOnly { get; set; } 
    public void GetOptions() 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class Version 
{ 
    public long Id { get; set; } 
    public string Description { get; set; } 
    public string Status { get; set; } 
    public float VersionNumber { get; set; } 
    public virtual PriceLevel PriceLevel { get; set; } 
    public DateTime EffectiveDate { get; set; } 
    public virtual ICollection<Model> Models { get; set; } 
    public virtual ICollection<InternCode> DataReleaseLevels { get; set; } 
} 

Таким образом, Version может относиться ко многим Model s, каждый из которых является DataCode. Но еще один Version может ссылаться на тот же набор Model s (отсюда ключевое слово virtual, которое Думаю, - это то, как вы это делаете). A PriceLevel также является DataCode. A Version также может иметь много InternCode s, каждый из которых является DataCode, но это еще одна история. Во всяком случае, в таблице DataCode много чего происходит в EF.

Мы имеем следующую DataInitializer кода:

var ModelList = new List<Model> 
{ 
    new Model { Code = "001-230", Description = "Model 230" }, 
    new Model { Code = "001-231", Description = "Model 231" }, 
    new Model { Code = "001-232", Description = "Model 232" }, 
    new Model { Code = "001-233", Description = "Model 233" }, 
    // and many more 
} 

var versions = new List<Entities.Version> 
{ 
    new Entities.Version { 
     VersionNumber=2.1F, 
     Description = "Version 2.1 for Model Group A", 
     EffectiveDate = DateTime.Parse("1/15/1995"), 
     Models=new List<Model> { 
      ModelList.Find(m => m.Code == "001-230"), 
      ModelList.Find(m => m.Code == "001-231"), 
      ModelList.Find(m => m.Code == "001-232"), 
      ModelList.Find(m => m.Code == "001-233"), 
     }, 
     Status = "Draft" 
    }, 
    new Entities.Version { 
     VersionNumber=2.2F, 
     Description = "Version 2.2 for Model Group A", 
     EffectiveDate = DateTime.Parse("7/15/1995"), 
     Models=new List<Model> { 
      ModelList.Find(m => m.Code == "001-230"), 
      ModelList.Find(m => m.Code == "001-231"), 
      ModelList.Find(m => m.Code == "001-232"), 
      ModelList.Find(m => m.Code == "001-233"), 
     }, 
     Status = "Draft" 
    }, 
    new Entities.Version { 
     VersionNumber=2.3F, 
     Description = "Version 2.3 for Model Group A", 
     EffectiveDate = DateTime.Parse("1/15/1996"), 
     Models=new List<Model> { 
      ModelList.Find(m => m.Code == "001-230"), 
      ModelList.Find(m => m.Code == "001-231"), 
      ModelList.Find(m => m.Code == "001-232"), 
      ModelList.Find(m => m.Code == "001-233"), 
     }, 
     Status = "Draft" 
    }        
}; 

После сохранения изменений, жертвуя курицу, и все другие вещи, мы находим, что DataCode таблицы в базе данных создают два столбцы с именем Version_VersionId и Version_VersionId1. Первый имеет нулевые значения, второй - Id из последней записи Version, которая была создана. По крайней мере, я ожидаю, что он создаст новый столбец Version_VersionId для каждого Version, членом которого является Model. Для меня это кажется ужасно неэффективным, но, по крайней мере, это сработает. Вместо этого данные, похоже, топают в предыдущих Version ссылках.

Я надеюсь, что мы сможем исправить это с помощью FluentAPI, но я понятия не имею, как это сделать. У кого-нибудь есть предложение?

ответ

1

Перед тем, как начать, после решения проблемы, обратите также внимание на public ICollection<string> Aliases { get; set; }, потому что не может быть сопоставлен таким образом.

Контекст очень важен. Для меня довольно странно, что у вас есть таблица DataCode (класс DataCode является абстрактным, поэтому вы - и EF - не можете его создать). Во всяком случае, используя этот контекст

public class TestContext : DbContext 
{ 
    public TestContext(DbConnection connection) : base(connection, true) { } 

    public DbSet<InternCode> InternCodes { get; set; } 
    public DbSet<Model> Models { get; set; } 
    public DbSet<Version> Versions { get; set; } 


} 

Три таблицы созданы, как и ожидалось. InternCode имеет Version_Id, а Model имеет Version_Id, потому что вы не указали что-либо в Model и InternCode о версии, поэтому EF предполагает, что один InternCode (и одна модель) имеет только одну версию

Для достижения одной модели (и одной InternCode) может быть связано с более чем одной версии вы можете сделать следующее:

public class TestContext : DbContext 
{ 
    public TestContext(DbConnection connection) : base(connection, true) { } 

    public DbSet<InternCode> InternCodes { get; set; } 
    public DbSet<Model> Models { get; set; } 
    public DbSet<Version> Versions { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add(new VersionMap()); 
    } 
} 

public class InternCode : DataCode 
{ 
    public string PrimaryRelationalOperator { get; set; } 
    public string PrimaryValue { get; set; } 
    public string SecondaryRelationalOperator { get; set; } 
    public string SecondaryValue { get; set; } 

    public virtual ICollection<Version> Versions { get; set; } 
} 

public class Model : DataCode 
{ 
    public ICollection<string> Aliases { get; set; } 
    public bool ExportOnly { get; set; } 
    public virtual ICollection<Version> Versions { get; set; } 
    public void GetOptions() 
    { 
     throw new NotImplementedException(); 
    } 
} 


public class VersionMap : EntityTypeConfiguration<Version> 
{ 
    public VersionMap() 
    { 
     // Relationships 
     HasMany(t => t.Models) 
      .WithMany(t => t.Versions); 

     HasMany(t => t.DataReleaseLevels) 
      .WithMany(t => t.Versions); 
    } 
} 

в этом случае вы увидите несколько таблиц, созданных (таблицы, чтобы выразить п к м) отношений

+0

Мы заметили, что псевдонимы не работает должным образом (или вообще). Что мы можем сделать для решения проблемы? Нужно ли создавать 'public class Alias' с' public long Id' и 'public string Alias' в качестве свойств? –

+0

Вы можете это сделать или, если вам не нужно искать по псевдонимам, вы можете добавить личное хранилище (нужно сопоставить его с помощью свободного интерфейса, а класс отображения должен быть внутренним классом объекта) и использовать его для компилировать Псевдонимы. – bubi

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