使用EF第一次加载程序会很慢,因为EF第一次会生成实体类和数据库的对应关系并做缓存,怎么解决这个问题呢?站在巨人的肩膀上将会省力很多,博客园的dudu已经给出了个解决方案(EF版本6.0以上)
主要代码如下:
using (var dbcontext = new CnblogsDbContext()){ var objectContext = ((IObjectContextAdapter)dbcontext).ObjectContext; var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace); mappingCollection.GenerateViews(new List());}
根据代码来看一个表对应一个操作类,而我的项目使用的是Code First并使用了仓储模式(EF的三种模式区别自行查找资料),所以要做修改。
我的项目结构如下:
public class Repository: DbContext, IRepository where T : class,new() { private static readonly string connection = ConfigurationManager.ConnectionStrings["connection"].ConnectionString; private DbSet _dbSet; public Repository() : base(connection) { } public DbSet Query { get { if (_dbSet == null) _dbSet = Set (); return _dbSet; } }}
使用的是泛型,所以我的解决方法是使用反射
解决方法:
private static void LoadEFViewMapping() { string[] items = { "Fish.Model" }; foreach (var item in items) { var data = Assembly.Load(item.Trim()); data.GetBaseClass() .Where(g => g.BaseType == typeof(MySqlBase)) .ToList() .ForEach(entity => { Type type = typeof(MySqlRepository<>); type = type.MakeGenericType(entity); var objectContext = ((IObjectContextAdapter)Activator.CreateInstance(type)).ObjectContext; var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace); mappingCollection.GenerateViews(new List()); }); data.GetBaseClass() .Where(g => g.BaseType == typeof(SqlServerBase)) .ToList() .ForEach(entity => { Type type = typeof(SqlServerRepository<>); type = type.MakeGenericType(entity); var objectContext = ((IObjectContextAdapter)Activator.CreateInstance(type)).ObjectContext; var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace); mappingCollection.GenerateViews(new List ()); }); } }
解释一下:因我所有的实体类需执行一个去除EF访问多余数据方法(具体参考:),所以所有实体都继承一个基类,而本项目同时使用MySql和SqlServer数据库所以有了MySqlBase和SqlServerBase类,这两个类都继承自基类BaseEntity,实体类根据访问数据库分别继承MySqlBase和SqlServerBase类