2015-01-02 10 views
9

Właśnie zacząłem pracować nad kodem ramowym jednostki pierwsze podejście, napisałem dwa podejścia poniżej i oba działają dobrze.modelBuilder.Configurations.Add i modelBuilder.Entity on OnModelCreating

Proszę dać mi znać, jakie są główne koncepcje leżące u podstaw obu podejść i co powinno nastąpić?

Podejście 1:Korzystanie EntityTypeConfiguration

public class BlogsMap : EntityTypeConfiguration<Blog> 
    { 
     public BlogsMap(string schema) 
     { 
      ToTable("BLOG"); 
      HasKey(t => t.BlogId); 
      Property(t => t.BlogId).HasColumnName("BLOGID"); 
      Property(t => t.Name).HasColumnName("NAME"); 
      Property(t => t.Url).HasColumnName("URL"); 
     } 

    } 


public class BlogContext : DbContext 
    { 
     public BlogContext(string name) 
      : base(name) 
     { 
     } 

     public IDbSet<Blog> BLOG { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Configurations.Add(new BlogMap(string.Empty)); 
     } 
    } 

Podejście 2:

public class Blog 
    { 
     public int BlogId { get; set; } 
     public string Name { get; set; } 
     public string Url { get; set; } 
     public virtual List<Post> Posts { get; set; } 
    } 


    public class BloggingContext : DbContext 
    {  

     public DbSet<Blog> Blogs { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Entity<Blog>(); 

     } 
    } 

Proszę podać mi koncepcji/blogi na podmiot, ponieważ ja właśnie zaczęło.

Odpowiedz

25

Masz kilka sposobów na skonfigurowanie swoich jednostek. Poniżej pokażę trzy sposoby, jeden za pomocą DataAnnotations i dwa przy użyciu Fluent Api.

Pierwszy wariant wykorzystuje funkcję DataAnnotations. Możesz użyć atrybutów (DataAnnotations) skonfigurować swoje jednostki i properties.DataAnnotations klas atrybutów przesłonięcia domyślnych kod najpierw konwencje:

[Table(“BLOGS”)] 
public class Blog 
{ 
    [Key] 
    [Column(“BLOGID”)] 
    public int BlogId { get; set; } 
    [Column(“NAME”)] 
    public string Name { get; set; } 
    [Column(“URL”)] 
    public string Url { get; set; } 

    public virtual List<Post> Posts { get; set; } 
} 
[Table(“POSTS”)] 
public class Post 
{ 
    [Key] 
    [Column(“POSTID”)] 
    public int PostId { get; set; } 
    [Column(“TEXT”)] 
    public string Text { get; set; } 

    public int BlogId { get; set; } 

    [ForeignKey("BlogId")] 
    public virtual BaseCard Blog { get; set; } 
} 

Następnie w swojej klasie kontekstu, nie trzeba zastąpić metodę OnModelCreating EF będzie użyć atrybutu do mapowania podmiotów i relacji (utworzy relacji 1 do wielu między blogu i post):

public class BlogContext : DbContext 
{ 
    public BlogContext(string name) 
     : base(name) 
    { 
    } 

    public IDbSet<Blog> Blogs { get; set; } 
    public IDbSet<Post> Posts { get; set; } 
} 

Konfiguracja z danymi adnotacji jest dość prosta i może być tylko to, czego szukasz dla. Ale adnotacje danych pozwalają tylko na dostęp do podzbioru możliwych konfiguracji (choć znacznie więcej niż dotychczas). Jednak Fluent API daje ci dostęp do jeszcze większej liczby, więc możesz go preferować z tego powodu. Dzięki Fluent Api nie musisz używać atrybutów do mapowania pól i relacji z twoich klas jednostek. Istnieją dwa sposoby korzystania z Fluent API:

1-mapping podmiotów (Pola i relacje) W sposobie OnModelCreating w kontekście (Twój drugi Aproach):

public class BloggingContext : DbContext 
{  

    public DbSet<Blog> Blogs { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Blog>().ToTable("BLOGS"); 

     modelBuilder.Entity<Blog>().HasKey(t => t.BlogId); 
     modelBuilder.Entity<Blog>().Property(t => t.BlogId).HasColumnName("BLOGID"); 
     modelBuilder.Entity<Blog>().Property(t => t.Name).HasColumnName("NAME"); 
     modelBuilder.Entity<Blog>().Property(t => t.Url).HasColumnName("URL"); 
     // The same with post 

     //mapping one-to-many relationship 
     modelBuilder.Entity<Post>().HasRequired(c => c.Blog) 
     .WithMany(s => s.Posts) 
     .HasForeignKey(c => c.BlogId); 

} 

2-drugiego wariantu użyciu Fluent Api tworzy klasy mapowania (Twoje pierwsze podejście). W ten sposób można skonfigurować podmiotów w klasach, które dziedziczą z EntityTypeConfiguration<TEntity>:

public class BlogMap : EntityTypeConfiguration<Blog> 
{ 
    public BlogMap() 
    { 
     ToTable("BLOGS"); 
     HasKey(t => t.BlogId); 
     Property(t => t.BlogId).HasColumnName("BLOGID"); 
     Property(t => t.Name).HasColumnName("NAME"); 
     Property(t => t.Url).HasColumnName("URL"); 
    } 

} 

public class PostMap : EntityTypeConfiguration<Post> 
{ 
    public PostMap() 
    { 
     ToTable("POSTS"); 
     HasKey(t => t.PostId); 
     Property(t => t.Text).HasColumnName("TEXT"); 

     //mapping the relationship 
     HasRequired(c => c.Blog) 
     .WithMany(s => s.Posts) 
     .HasForeignKey(c => c.BlogId); 

    } 
} 

Następnie włączyć mapowania w swoim kontekście należy dodać je w metodzie OnModelCreating:

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

Najlepszym sposobem aby dodać konfiguracje jest w ten sposób:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    var typesToRegister = Assembly.GetExecutingAssembly().GetTypes() 
     .Where(type => !String.IsNullOrEmpty(type.Namespace)) 
     .Where(type => type.BaseType != null && type.BaseType.IsGenericType 
      && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)); 
     foreach (var type in typesToRegister) 
     { 
      dynamic configurationInstance = Activator.CreateInstance(type); 
      modelBuilder.Configurations.Add(configurationInstance); 
     } 
     base.OnModelCreating(modelBuilder); 
} 

Ten ostatni wariant (pierwsze podejście) jest dla mnie najlepszy ze względu na nie trzeba dotykać yo ur klasy modelu (dodawanie atrybutów), aby określić, co chcesz i jest bardziej elastyczny, jeśli chcesz dodać nowy podmiot lub coś zmienić.

+0

Miałem niektórych programistów, którzy mieli domyślne parametry dla swoich konstruktorów.Musiał się zmienić, aby korzystać z biblioteki ImpromptuInterface, aby ją uruchomić. foreach (typ var w typeToRegister) { dynamic configurationInstance = Impromptu.InvokeConstructor (type); Serilog.Log.Debug ("{Metoda} Dodanie mapy modelBuilder dla {TypeName}", "OnModelCreating", type.Name); modelBuilder.Configurations.Add (configurationInstance); } – Jafin

+0

I <3 tę odpowiedź. Czy jest dla mnie sposób na "ukochanie", żebym mógł do niego wrócić ... – mmcrae

+0

Mam tylko pytanie, gdzie umieścisz kod mapy w swojej części 2? Czy tworzysz osobny folder Maps i tworzysz oddzielne pliki BlogMaps i PostMaps, aby zawierały odpowiedni kod, podobny do tego, jak zrobiłbyś to przy FluentValidation? –