2016-07-01 1 views
0

я определяю класс на основе записи каталогизации органа, который имеет ряд самостоятельных ссылок детей, а именно:Определить имя столбца для автореферентного свойства списка в EF

public class Authority 
{ 
    public long ID { get; set; } 
    public string Term { get; set; } 
    public string Language { get; set; } 
    public bool PreferredTerm { get; set; } 
    public TermStatus TermStatus { get; set; } 
    public Authority Use { get; set; } 
    public List<Authority> UsedFor { get; set; } 
    public List<Authority> Equivalent { get; set; } 
    public List<Authority> Broader { get; set; } 
    public List<Authority> Narrower { get; set; } 
} 

Когда создаются столбцы в таблице «Орган» в базовой базе данных SQL имена столбцов для каждого из свойств «Список» - это «Административные_ид», «Администратор_ID1», «Административный_ID2» и «Административный_ID3».

Я бы предпочел, чтобы имена столбцов были «UsedFor», «Equivalent», «Broader» и «Narrower». Я попытался использовать атрибут [Column ("name")], но он не работает. Как я могу это сделать в Code First?

ответ

0

Попробуйте это. Я не уверен, что определения внешних ключей должны быть в классе POCO (вы можете попытаться их опустить).

public class Authority 
{ 
    [Key()] 
    public long ID { get; set; } 
    public string Term { get; set; } 
    public string Language { get; set; } 
    public bool PreferredTerm { get; set; } 
    public TermStatus TermStatus { get; set; } 
    public Authority Use { get; set; } 

    [Required] 
    public long Authority_ID { get; set; } 

    [Required] 
    public long Authority_ID1 { get; set; } 

    [Required] 
    public long Authority_ID2 { get; set; } 

    [Required] 
    public long Authority_ID3 { get; set; } 

    [ForeignKey("Authority_ID")] 
    public ICollection<Authority> UsedFor { get; set; } 

    [ForeignKey("Authority_ID1")] 
    public ICollection<Authority> Equivalent { get; set; } 

    [ForeignKey("Authority_ID2")] 
    public ICollection<Authority> Broader { get; set; } 

    [ForeignKey("Authority_ID3")] 
    public ICollection<Authority> Narrower { get; set; } 
} 
0

Вы можете использовать [InverseProperty ("name")] для своего списка. После этого имена ваших колонок будут «UsedFor_ID», «Equilavent_ID» и т. Д. В базе данных (не совсем соответствующий вашему вопросу, извините!).

public class Authority 
{ 
    [InverseProperty("UsedFor")]  
    public List<Authority> UsedFor { get; set; } 
    [InverseProperty("Equivalent")] 
    public List<Authority> Equivalent { get; set; }  
} 

Дальше по адресу: https://msdn.microsoft.com/en-us/data/gg193958 http://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in-code-first.aspx

0

Спасибо за предложения. То, что работало в том, чтобы использовать [ForeignKey] для ссылки и [Колонка], чтобы переименовать столбец, т.е.

[Column("Use")] 
    public long? UseID { get; set; } 

    [ForeignKey("UseID")] 
    public List<Authority> Use { get; set; } 

Однако я также сделал критическую ошибку в определении, потому что даже если я определил столбец в виде списка, код выше заканчивается ключом 1 к 0/1. Мне действительно нужно было добавить в дочернюю таблицу, чтобы принять множество значений.

Мой окончательный код выглядит следующим образом, и лежащие в их основе названия столбцов читаемый вместо Authority_ID, Authority_ID1, Authority_ID2 и Authority_ID3:

public class Authority 
{ 
    public long ID { get; set; } 
    public string Term { get; set; } 
    public string Language { get; set; } 
    public bool PreferredTerm { get; set; } 
    public TermStatus TermStatus { get; set; } 

    //Establish 1-to-0/1 self-referencing key 
    [Column("Use")] 
    public long? UseID { get; set; } 

    [ForeignKey("UseID")] 
    public List<Authority> Use { get; set; } 

    //Establis 1-many foreign keys 
    [ForeignKey("UsedFor")] 
    public List<AuthorityList> UsedFor { get; set; } 

    [ForeignKey("Equivalent")] 
    public List<AuthorityList> Equivalent { get; set; } 

    [ForeignKey("Broader")] 
    public List<AuthorityList> Broader { get; set; } 

    [ForeignKey("Narrower")] 
    public List<AuthorityList> Narrower { get; set; } 
} 

public class AuthorityList 
{ 
    public long ID { get; set; } 
    public long AuthorityID { get; set; } 
    public long? UsedFor { get; set; } 
    public long? Equivalent { get; set; } 
    public long? Broader { get; set; } 
    public long? Narrower { get; set; } 
} 

Для того, чтобы предотвратить каскадирование удалений мешая Я также добавил Ниже в моем контексте базы данных (БД затрагивает целые не только эти таблицы):

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 
0

Обновленный ответ:

Используя вышеизложенное, я получил базовую структуру таблицы, которую я хотел, но не те функции, которые мне нужны, так как EF решил, что в этой конфигурации он будет отображать 1-1-отношения вместо 1-M. Ответ заключался в понимании того, как EntityFramework управляет связыванием «многие-ко-многим». Даже это можно настроить несколькими способами в зависимости от того, хотите ли вы только два отношения 1-М или больше. Я хочу шесть.

В конце концов, эта конфигурация дала мне функциональность, которую я хотел, за счет наличия менее идеальной структуры базы данных.

public class Tag 
{ 
    public int ID { get; set; } 
    public string Term { get; set; } 

    public virtual ICollection<Tag> Broader { get; set; } 
    public virtual ICollection<Tag> Narrower { get; set; } 
    public virtual ICollection<Tag> Equivalent { get; set; } 
    public virtual ICollection<Tag> Related { get; set; } 
    public virtual ICollection<Tag> Use { get; set; } 
    public virtual ICollection<Tag> Usefor { get; set; } 

    public Tag() 
    { 
     Broader = new HashSet<Tag>(); 
     Narrower = new HashSet<Tag>(); 
     Equivalent = new HashSet<Tag>(); 
     Related = new HashSet<Tag>(); 
     Use = new HashSet<Tag>(); 
     Usefor = new HashSet<Tag>(); 
    } 
} 

Я также необходимо добавить следующие данные в процедуру «OnModelCreating» в контексте базы данных:

modelBuilder.Entity<Tag>() 
     .HasMany(x => x.Broader) 
     .WithMany() 
     .Map(x => x.MapLeftKey("TagID").MapRightKey("BroaderID").ToTable("TagBroader")); 

    modelBuilder.Entity<Tag>() 
     .HasMany(x => x.Equivalent) 
     .WithMany() 
     .Map(x => x.MapLeftKey("TagID").MapRightKey("EquivalentID").ToTable("TagEquivalent")); 

    modelBuilder.Entity<Tag>() 
     .HasMany(x => x.Narrower) 
     .WithMany() 
     .Map(x => x.MapLeftKey("TagID").MapRightKey("NarrowerID").ToTable("TagNarrower")); 

    modelBuilder.Entity<Tag>() 
      .HasMany(x => x.Related) 
      .WithMany() 
      .Map(x => x.MapLeftKey("TagID").MapRightKey("RelatedID").ToTable("TagRelated")); 

    modelBuilder.Entity<Tag>() 
     .HasMany(x => x.Use) 
     .WithMany() 
     .Map(x => x.MapLeftKey("TagID").MapRightKey("UsedID").ToTable("TagUse")); 

    modelBuilder.Entity<Tag>() 
     .HasMany(x => x.Usedfor) 
     .WithMany() 
     .Map(x => x.MapLeftKey("TagID").MapRightKey("UsedforID").ToTable("TagUsedfor")); 

Для тестирования я использовал следующее:

 //Broader/Narrower example 
     var music = new Tag{ Term = "Music"}; 
     var jazz = new Tag{ Term = "Jazz Music" }; 
     var classical = new Tag{ Term = "Classical Music" }; 

     music.Narrower.Add(jazz); 
     music.Narrower.Add(classical); 
     jazz.Broader.Add(music); 
     classical.Broader.Add(music); 

     //Equivalent example 
     var zucchini = new Tag{ Term = "Zucchini" }; 
     var courgette = new Tag{ Term = "Courgette" }; 

     zucchini.Equivalent.Add(courgette); 
     courgette.Equivalent.Add(zucchini); 

     context.Tags.Add(music); 
     context.Tags.Add(jazz); 
     context.Tags.Add(classical); 
     context.Tags.Add(zucchini); 
     context.Tags.Add(courgette); 
     context.SaveChanges();