我刚开始研究实体框架代码的第一种方法,我在下面写了两种方法,两种方法都运行良好。
请让我知道这两种方法背后的核心概念是什么,应该遵循什么?
方法1: 使用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));
}
}
方法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>();
}
}
请提供关于实体的概念/博客,因为我刚开始。
答案 0 :(得分:31)
您可以通过多种方式配置实体。下面我将展示三种方式,一种使用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将使用该属性来映射您的实体和关系(它将在博客和帖子之间创建一对多关系):< / p>
public class BlogContext : DbContext
{
public BlogContext(string name)
: base(name)
{
}
public IDbSet<Blog> Blogs { get; set; }
public IDbSet<Post> Posts { get; set; }
}
使用数据进行配置注释非常简单,可能正是您所需要的。但是Data Annotations只允许您访问可能配置的子集(尽管远远超过您目前所见)。但是,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的第二个变体是创建映射类(Your First Approach)。这样,您可以在继承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);
}
最后一个变体(第一种方法)对我来说是最好的,因为您不必触摸您的模型类(添加属性)来指定您想要的内容,并且如果您想要添加新实体或更灵活,则更灵活改变一些事情。
答案 1 :(得分:0)
string nspace = "CompanyAdministration.data.Models";
var q = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass && t.Namespace == nspace && t.Name[0] != '<' && t.Name.Substring(0, 2) != "BOX" && t.Name != "CAContext"
select t;
foreach (Type t in q)
{
try
{
MethodInfo method = modelBuilder.GetType().GetMethod("Entity");
method = method.MakeGenericMethod(new Type[] { t });
method.Invoke(modelBuilder, null);
}
catch
{
}
}
base.OnModelCreating(modelBuilder);