2013-02-16 2 views
0

У меня есть общий тип, который я хотел бы представлять в базе данных. Мне нужно знать, если это возможно с первым кодом или плохим дизайном. (Укажите, пожалуйста, источники ваших рассуждений).Как определить свойство навигации EF5 для нескольких типов

Вот макет:

public class A 
{ 
    public Guid Id; 
    public Guid ParentId; // Points to either B or C 
    public string Foo; 
} 

public class B 
{ 
    public Guid Id; 
    public virtual ICollection<A> ManyA { get; set; } 
    // Other fields 
} 

public class C 
{ 
    public Guid Id; 
    public virtual ICollection<A> ManyA { get; set; } 
    // Other fields 
} 

мне удалось GUID первичные ключи с помощью [DatabaseGenerated(DatabaseGeneratedOption.Identity)] аннотацию, который я считаю, что это стало возможным.

Цель состоит в том, чтобы держать A-table простым; Я хотел бы не иметь B_IdC_Id и столбцов, как я думаю, что они не нужны, и может быть D типа в будущем, что имеет много A так же, как и BC. Кроме того, этот сценарий используется для нескольких других отношений.

Я думаю, что дух проблемы очевиден, однако члены класса, связанные с EF, просто для иллюстрации. Если им нужно измениться, пусть будет так.

(Прошу прощения за надуманный пример, однако разоблачение истинной природы этого, ИМО, не уточняет проблему).

Кроме того, я пробовал искать часы! Я не знаю правильной номенклатуры, чтобы найти подходящий ответ. Я довольно новичок в базах данных и EF в целом.

ответ

0

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

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var context = new Ctx()) 
     { 
      var b = new B(); 
      var c = new C(); 
      b.ManyA.Add(new A()); 
      c.ManyA.Add(new A()); 

      context.Cs.Add(c); 
      context.Bs.Add(b); 

      context.SaveChanges(); 
     } 
    } 
} 

public class Ctx : DbContext 
{ 
    public DbSet<A> As { get; set; } 
    public DbSet<B> Bs { get; set; } 
    public DbSet<C> Cs { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<BaseClass>() 
      .HasMany<A>(b => b.ManyA) 
      .WithRequired(a => a.BaseObject) 
      .WillCascadeOnDelete(true); 
    } 
} 

public class BaseClass 
{ 
    public BaseClass() { ManyA = new HashSet<A>(); } 

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid Id { get; set; } 
    public virtual ICollection<A> ManyA { get; set; } 
} 

public class A 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid Id { get; set; } 
    public BaseClass BaseObject { get; set; } 
    public string Foo { get; set; } 
} 

public class B : BaseClass 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid Id { get; set; } 
    public string SomeProperty { get; set; } 
} 

public class C : BaseClass 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid Id { get; set; } 
    public int SomeOtherProperty { get; set; } 
} 

И, основываясь на this Msdn article, приведет к компоновке базы данных Таблица Per иерархии. TPH работает лучше против TPT, о чем я думал, может быть ответом.

Я действительно надеялся на что-то более простое, но производительность в нижней строке, Afterall

+0

Примечание: использование Guid в этом случае является спорным. –

0

Не используйте Guid для создания индекса, почему вы выбираете жесткий путь? : S

использовать DataAnnotations как пример:

Класс: класс

using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.ComponentModel.DataAnnotations; 
using System.ComponentModel.DataAnnotations.Schema; 
using System.Web.Mvc; 

namespace app.Models 
{ 
    [Table("A")] 
    public class A 
    { 

     [Key] 
     public int AId { get; set; } 

     [Required(ErrorMessage = "Campo obrigatório")] 
     [DisplayName("Title")] 
     [StringLength(100)] 
     public string Title { get; set; } 
     public virtual ICollection<B> bCollection { get; set; } 
    } 
} 

B:

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.ComponentModel.DataAnnotations.Schema; 
using System.Web.Mvc; 

namespace app.Models 
{ 
    [Table("B")] 
    public class B 
    { 
     [ScaffoldColumn(false)] 
     [Key] 
     public int BId { get; set; } 

     [DisplayName("Description")] 
     [StringLength(100)] 
     public string Description { get; set; } 

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

Вы можете посмотреть более подробную информацию здесь: link !!! Для получения более подробной информации о Ef5 аннотаций данных: link

+0

Я выбрал 'Guid' из-за того, что' ссылки Ā' как '' b' и типов C'; Поле 'ParentId' на' A' потенциально может быть неоднозначным, если 'B' и' C' имеют только идентификаторы 'int'. –

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

  • Нет связанных вопросов^_^