forked from gmf520/osharp-v4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDbContextInitializerBase.cs
171 lines (153 loc) · 6.55 KB
/
DbContextInitializerBase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// -----------------------------------------------------------------------
// <copyright file="DbContextInitializerBase.cs" company="OSharp开源团队">
// Copyright (c) 2014-2015 OSharp. All rights reserved.
// </copyright>
// <last-editor>郭明锋</last-editor>
// <last-date>2015-06-28 16:07</last-date>
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using OSharp.Core.Data;
using OSharp.Data.Entity.Migrations;
using OSharp.Data.Entity.Properties;
using OSharp.Utility.Extensions;
namespace OSharp.Data.Entity
{
/// <summary>
/// 数据上下文初始化基类
/// </summary>
public abstract class DbContextInitializerBase<TDbContext>
: DbContextInitializerBase
where TDbContext : DbContext, IUnitOfWork, new()
{
/// <summary>
/// 初始化一个<see cref="DbContextInitializerBase"/>类型的新实例
/// </summary>
protected DbContextInitializerBase()
{
CreateDatabaseInitializer = new CreateDatabaseIfNotExists<TDbContext>();
MigrateInitializer = new MigrateDatabaseToLatestVersion<TDbContext, AutoMigrationsConfiguration<TDbContext>>();
}
/// <summary>
/// 获取或设置 设置数据库创建初始化,默认为<see cref="CreateDatabaseIfNotExists{TDbContext}"/>
/// </summary>
public IDatabaseInitializer<TDbContext> CreateDatabaseInitializer { get; set; }
/// <summary>
/// 获取或设置 数据迁移策略,默认为自动迁移
/// </summary>
public IDatabaseInitializer<TDbContext> MigrateInitializer { get; set; }
/// <summary>
/// 重写以筛选出当前上下文的实体映射信息
/// </summary>
protected override IEnumerable<IEntityMapper> EntityMappersFilter(IEnumerable<IEntityMapper> entityMappers)
{
Type contextType = typeof(TDbContext);
Expression<Func<IEntityMapper, bool>> predicate = m => m.DbContextType == contextType;
if (contextType == typeof(DefaultDbContext))
{
predicate = predicate.Or(m => m.DbContextType == null);
}
return entityMappers.Where(predicate.Compile());
}
/// <summary>
/// 数据库初始化实现,设置数据库初始化策略,并进行EntityFramework的预热
/// </summary>
protected override void ContextInitialize()
{
TDbContext context = new TDbContext();
IDatabaseInitializer<TDbContext> initializer;
if (!context.Database.Exists())
{
initializer = CreateDatabaseInitializer;
}
else
{
initializer = MigrateInitializer;
}
Database.SetInitializer(initializer);
ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
StorageMappingItemCollection mappingItemCollection = (StorageMappingItemCollection)objectContext.ObjectStateManager
.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
mappingItemCollection.GenerateViews(new List<EdmSchemaError>());
context.Dispose();
}
}
/// <summary>
/// 数据上下文初始化基类
/// </summary>
public abstract class DbContextInitializerBase
{
/// <summary>
/// 初始化一个<see cref="DbContextInitializerBase"/>类型的新实例
/// </summary>
protected DbContextInitializerBase()
{
MapperAssemblies = new List<Assembly>();
EntityMappers = new ReadOnlyDictionary<Type, IEntityMapper>(new Dictionary<Type, IEntityMapper>());
}
/// <summary>
/// 获取或设置 实体映射程序集
/// </summary>
public ICollection<Assembly> MapperAssemblies { get; private set; }
/// <summary>
/// 获取 当前上下文的实体映射信息集合
/// </summary>
public IReadOnlyDictionary<Type, IEntityMapper> EntityMappers { get; private set; }
/// <summary>
/// 执行数据上下文初始化
/// </summary>
public void Initialize()
{
EntityMappersInitialize();
ContextInitialize();
}
/// <summary>
/// 初始化实体映射类型
/// </summary>
private void EntityMappersInitialize()
{
if (MapperAssemblies.Count == 0)
{
throw new InvalidOperationException(Resources.DbContextInitializerBase_MapperAssembliesIsEmpty.FormatWith(this.GetType().FullName));
}
Type baseType = typeof(IEntityMapper);
Type[] mapperTypes = MapperAssemblies.SelectMany(assembly => assembly.GetTypes())
.Where(type => baseType.IsAssignableFrom(type) && type != baseType && !type.IsAbstract).ToArray();
IEnumerable<IEntityMapper> entityMappers = mapperTypes.Select(type => Activator.CreateInstance(type) as IEntityMapper).ToList();
entityMappers = EntityMappersFilter(entityMappers);
IDictionary<Type, IEntityMapper> dict = new Dictionary<Type, IEntityMapper>();
foreach (IEntityMapper mapper in entityMappers)
{
Type baseMapperType = mapper.GetType().BaseType;
if (baseMapperType == null)
{
continue;
}
Type entityType = baseMapperType.GetGenericArguments().FirstOrDefault();
if (entityType == null || dict.ContainsKey(entityType))
{
continue;
}
dict[entityType] = mapper;
}
EntityMappers = new ReadOnlyDictionary<Type, IEntityMapper>(dict);
}
/// <summary>
/// 重写以筛选出当前上下文的实体映射信息
/// </summary>
protected abstract IEnumerable<IEntityMapper> EntityMappersFilter(IEnumerable<IEntityMapper> entityMappers);
/// <summary>
/// 数据库初始化实现,设置数据库初始化策略,并进行EntityFramework的预热
/// </summary>
protected abstract void ContextInitialize();
}
}