Ответ 1
У вас есть несколько способов настройки ваших объектов. Ниже я покажу три способа, используя DataAnnotations и два, используя Fluent Api.
В первом варианте используется DataAnnotations. Вы можете использовать атрибуты (DataAnnotations) для настройки классов сущностей и свойств. Атрибуты DataAnnotations переопределяют стандартные соглашения Code First:
[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; }
}
Затем в вашем контексте класс вам не нужно переопределять метод OnModelCreating, EF будет использовать атрибут для сопоставления ваших сущностей и отношений (он создаст отношения "один ко многим" между блогом и сообщением):
public class BlogContext : DbContext
{
public BlogContext(string name)
: base(name)
{
}
public IDbSet<Blog> Blogs { get; set; }
public IDbSet<Post> Posts { get; set; }
}
Настройка с аннотациями данных довольно проста, и это может быть именно то, что вы ищете. Но аннотации данных позволяют вам получить доступ к подмножеству возможных конфигураций (хотя гораздо больше, чем вы видели до сих пор). Однако Fluent API дает вам доступ к еще большему, поэтому вы можете предпочесть его по этой причине. С Fluent Api вам не нужно использовать атрибуты для сопоставления полей и отношений ваших классов объектов. Существует два способа использования Fluent Api:
1-Сопоставление сущностей (полей и отношений) в методе OnModelCreating
в вашем контексте (ваш второй 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-Второй вариант с использованием Fluent Api создает классы сопоставления (ваш первый подход). Таким образом, вы настраиваете объекты Entities в классах, наследующих 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);
}
}
Затем, чтобы включить сопоставления в ваш контекст, вам нужно добавить их в метод OnModelCreating
:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new BlogMap());
modelBuilder.Configurations.Add(new PostMap());
}
Лучший способ добавления конфигураций заключается в следующем:
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);
}
Этот последний вариант (первый подход) для меня является лучшим из-за того, что вам не нужно прикасаться к вашим классам моделей (добавление атрибутов), чтобы указать, что вы хотите, и является более гибким, если вы хотите добавить новый объект или изменить что-то.