mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
支持Fluent API .以继承接口的形式配置实体的。
This commit is contained in:
parent
352ceceb23
commit
c88706be3c
@ -1,3 +1,4 @@
|
|||||||
|
using efcore_to_freesql.Entitys;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
@ -14,6 +15,15 @@ namespace efcore_to_freesql.DBContexts
|
|||||||
{
|
{
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
Fsql.CodeFirst.ConfigEntity(modelBuilder.Model); //ͬ²½ÅäÖÃ
|
Fsql.CodeFirst.ConfigEntity(modelBuilder.Model); //ͬ²½ÅäÖÃ
|
||||||
|
|
||||||
|
//配置单个
|
||||||
|
Fsql.CodeFirst.ApplyConfiguration(new SongConfiguration());
|
||||||
|
|
||||||
|
//批量量配置
|
||||||
|
//Fsql.CodeFirst.ApplyConfigurationsFromAssembly(typeof(SongConfiguration).Assembly);
|
||||||
|
|
||||||
|
Fsql.CodeFirst.SyncStructure<Song>();
|
||||||
|
|
||||||
}
|
}
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using efcore_to_freesql.Entitys;
|
using efcore_to_freesql.Entitys;
|
||||||
using FreeSql;
|
using FreeSql;
|
||||||
|
using FreeSql.Extensions.EfCoreFluentApi;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
using System;
|
using System;
|
||||||
@ -178,4 +179,27 @@ public static class CodeFirstExtensions
|
|||||||
cf.SyncStructure<SongType>();
|
cf.SyncStructure<SongType>();
|
||||||
cf.SyncStructure<Song>();
|
cf.SyncStructure<Song>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SongConfiguration : FreeSql.Extensions.EfCoreFluentApi.IEntityTypeConfiguration<Song>
|
||||||
|
{
|
||||||
|
public void Configure(EfCoreTableFluent<Song> eb)
|
||||||
|
{
|
||||||
|
eb.ToTable("tb_song_config");
|
||||||
|
eb.Ignore(a => a.Field1);
|
||||||
|
eb.Property(a => a.Title).HasColumnType("varchar(50)").IsRequired();
|
||||||
|
eb.Property(a => a.Url).HasMaxLength(100);
|
||||||
|
|
||||||
|
eb.Property(a => a.RowVersion).IsRowVersion();
|
||||||
|
eb.Property(a => a.CreateTime).HasDefaultValueSql("current_timestamp");
|
||||||
|
|
||||||
|
eb.HasKey(a => a.Id);
|
||||||
|
eb.HasIndex(a => a.Title).IsUnique().HasName("idx_tb_song1111");
|
||||||
|
|
||||||
|
//一对多、多对一
|
||||||
|
eb.HasOne(a => a.Type).HasForeignKey(a => a.TypeId).WithMany(a => a.Songs);
|
||||||
|
|
||||||
|
//多对多
|
||||||
|
eb.HasMany(a => a.Tags).WithMany(a => a.Songs, typeof(Song_tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -28,7 +28,7 @@ namespace efcore_to_freesql
|
|||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
//Fsql.CodeFirst.EfCoreFluentApiTestGeneric();
|
//Fsql.CodeFirst.EfCoreFluentApiTestGeneric();
|
||||||
Fsql.CodeFirst.EfCoreFluentApiTestDynamic();
|
//Fsql.CodeFirst.EfCoreFluentApiTestDynamic();
|
||||||
|
|
||||||
BaseDBContext.Fsql = Fsql;
|
BaseDBContext.Fsql = Fsql;
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
using FreeSql;
|
using FreeSql;
|
||||||
using FreeSql.DataAnnotations;
|
using FreeSql.DataAnnotations;
|
||||||
using FreeSql.Extensions.EfCoreFluentApi;
|
using FreeSql.Extensions.EfCoreFluentApi;
|
||||||
@ -34,4 +36,103 @@ partial class FreeSqlDbContextExtensions
|
|||||||
codeFirst.ConfigEntity(entityType, tf => modelBuilder(new EfCoreTableFluent(cf._orm, tf, entityType)));
|
codeFirst.ConfigEntity(entityType, tf => modelBuilder(new EfCoreTableFluent(cf._orm, tf, entityType)));
|
||||||
return codeFirst;
|
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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user