mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-18 20:08:15 +08:00
支持Fluent API .以继承接口的形式配置实体的。
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using FreeSql;
|
||||
using FreeSql.DataAnnotations;
|
||||
using FreeSql.Extensions.EfCoreFluentApi;
|
||||
@ -34,4 +36,103 @@ partial class FreeSqlDbContextExtensions
|
||||
codeFirst.ConfigEntity(entityType, tf => modelBuilder(new EfCoreTableFluent(cf._orm, tf, entityType)));
|
||||
return codeFirst;
|
||||
}
|
||||
|
||||
public static ICodeFirst ApplyConfiguration<TEntity>(this ICodeFirst codeFirst, IEntityTypeConfiguration<TEntity> configuration) where TEntity : class
|
||||
{
|
||||
return codeFirst.Entity<TEntity>(eb =>
|
||||
{
|
||||
configuration.Configure(eb);
|
||||
});
|
||||
}
|
||||
#if net40
|
||||
#else
|
||||
static IEnumerable<MethodInfo> GetExtensionMethods(this Assembly assembly, Type extendedType)
|
||||
{
|
||||
var query = from type in assembly.GetTypes()
|
||||
where !type.IsGenericType && !type.IsNested
|
||||
from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
where method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false)
|
||||
where method.GetParameters()[0].ParameterType == extendedType
|
||||
select method;
|
||||
return query;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据Assembly扫描所有继承IEntityTypeConfiguration<T>的配置类
|
||||
/// </summary>
|
||||
/// <param name="codeFirst"></param>
|
||||
/// <param name="assembly"></param>
|
||||
/// <param name="predicate"></param>
|
||||
/// <returns></returns>
|
||||
public static ICodeFirst ApplyConfigurationsFromAssembly(this ICodeFirst codeFirst, Assembly assembly, Func<Type, bool> predicate = null)
|
||||
{
|
||||
IEnumerable<TypeInfo> typeInfos = assembly.DefinedTypes.Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition);
|
||||
|
||||
MethodInfo methodInfo = typeof(FreeSqlDbContextExtensions).Assembly.GetExtensionMethods(typeof(ICodeFirst))
|
||||
.Single((e) => e.Name == "Entity" && e.ContainsGenericParameters);
|
||||
|
||||
if (methodInfo == null) return codeFirst;
|
||||
|
||||
foreach (TypeInfo constructibleType in typeInfos)
|
||||
{
|
||||
if (constructibleType.GetConstructor(Type.EmptyTypes) == null || predicate != null && !predicate(constructibleType))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var @interface in constructibleType.GetInterfaces())
|
||||
{
|
||||
if (@interface.IsGenericType && @interface.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>))
|
||||
{
|
||||
var type = @interface.GetGenericArguments().First();
|
||||
var efFluentType = typeof(EfCoreTableFluent<>).MakeGenericType(type);
|
||||
var actionType = typeof(Action<>).MakeGenericType(efFluentType);
|
||||
|
||||
//1.需要实体和Configuration配置
|
||||
//codeFirst.Entity<ToDoItem>(eb =>
|
||||
//{
|
||||
// new ToDoItemConfiguration().Configure(eb);
|
||||
//});
|
||||
|
||||
//2.需要实体
|
||||
//Action<EfCoreTableFluent<ToDoItem>> x = new Action<EfCoreTableFluent<ToDoItem>>(e =>
|
||||
//{
|
||||
// object o = Activator.CreateInstance(constructibleType);
|
||||
// constructibleType.GetMethod("ApplyConfiguration")?.Invoke(o, new object[1] { e });
|
||||
//});
|
||||
//codeFirst.Entity<ToDoItem>(x);
|
||||
|
||||
//3.实现动态调用泛型委托
|
||||
DelegateBuilder delegateBuilder = new DelegateBuilder(constructibleType);
|
||||
MethodInfo applyconfigureMethod = delegateBuilder.GetType().GetMethod("ApplyConfiguration")?.MakeGenericMethod(type);
|
||||
if (applyconfigureMethod == null) continue;
|
||||
Delegate @delegate = Delegate.CreateDelegate(actionType, delegateBuilder, applyconfigureMethod);
|
||||
|
||||
methodInfo.MakeGenericMethod(type).Invoke(null, new object[2]
|
||||
{
|
||||
codeFirst,
|
||||
@delegate
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codeFirst;
|
||||
}
|
||||
class DelegateBuilder
|
||||
{
|
||||
private readonly Type type;
|
||||
|
||||
public DelegateBuilder(Type type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
public void ApplyConfiguration<T>(EfCoreTableFluent<T> ex)
|
||||
{
|
||||
object o = Activator.CreateInstance(type);
|
||||
type.GetMethod("Configure")?.Invoke(o, new object[1] { ex });
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
namespace FreeSql.Extensions.EfCoreFluentApi
|
||||
{
|
||||
public interface IEntityTypeConfiguration<TEntity> where TEntity : class
|
||||
{
|
||||
void Configure(EfCoreTableFluent<TEntity> model);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user