mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-06-26 21:13:13 +00:00
1.6.1
This commit is contained in:
@ -40,7 +40,7 @@ namespace Esiur.Stores.EntityCore
|
||||
//internal object _PrimaryId;
|
||||
|
||||
public event DestroyedEvent OnDestroy;
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
//public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotMapped]
|
||||
public Instance Instance { get; set; }
|
||||
@ -66,7 +66,7 @@ namespace Esiur.Stores.EntityCore
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
OnDestroy?.Invoke(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,31 +45,25 @@ namespace Esiur.Stores.EntityCore
|
||||
Dictionary<Type, Dictionary<object, WeakReference>> DB = new Dictionary<Type, Dictionary<object, WeakReference>>();
|
||||
object DBLock = new object();
|
||||
|
||||
internal struct TypeInfo
|
||||
{
|
||||
public string Name;
|
||||
public IEntityType Type;
|
||||
public PropertyInfo PrimaryKey;
|
||||
}
|
||||
Dictionary<string, EntityTypeInfo> TypesByName = new Dictionary<string, EntityTypeInfo>();
|
||||
internal Dictionary<Type, EntityTypeInfo> TypesByType = new Dictionary<Type, EntityTypeInfo>();
|
||||
|
||||
Dictionary<string, TypeInfo> TypesByName = new Dictionary<string, TypeInfo>();
|
||||
internal Dictionary<Type, TypeInfo> TypesByType = new Dictionary<Type, TypeInfo>();
|
||||
[Attribute]
|
||||
public Func<DbContext> Getter { get; set; }
|
||||
|
||||
|
||||
|
||||
bool Loaded;
|
||||
|
||||
public AsyncReply<IResource> Get(string path)
|
||||
{
|
||||
var p = path.Split('/');
|
||||
var ti = TypesByName[p[0]];
|
||||
var id = Convert.ChangeType(p[1], ti.PrimaryKey.PropertyType);// Convert.ToInt32();
|
||||
var id = Convert.ChangeType(p[1], ti.PrimaryKey.PropertyType);
|
||||
|
||||
|
||||
var db = DbContextProvider();
|
||||
// Get db
|
||||
var db = Getter();
|
||||
var res = db.Find(ti.Type.ClrType, id);
|
||||
var ent = db.Entry(res);
|
||||
|
||||
// load navigation properties
|
||||
var ent = db.Entry(res);
|
||||
foreach (var rf in ent.References)
|
||||
rf.Load();
|
||||
|
||||
@ -78,12 +72,11 @@ namespace Esiur.Stores.EntityCore
|
||||
|
||||
public AsyncReply<bool> Put(IResource resource)
|
||||
{
|
||||
if (resource is EntityStore)
|
||||
if (resource == this)
|
||||
return new AsyncReply<bool>(true);
|
||||
|
||||
var type = ResourceProxy.GetBaseType(resource);//.GetType().;
|
||||
var type = ResourceProxy.GetBaseType(resource);
|
||||
|
||||
//var eid = (resource as EntityResource)._PrimaryId;// (int)resource.Instance.Variables["eid"];
|
||||
|
||||
var eid = TypesByType[type].PrimaryKey.GetValue(resource);
|
||||
|
||||
@ -112,11 +105,12 @@ namespace Esiur.Stores.EntityCore
|
||||
}
|
||||
}
|
||||
|
||||
[Attribute]
|
||||
public Func<DbContext> DbContextProvider { get; set; }
|
||||
|
||||
[Attribute]
|
||||
public DbContextOptionsBuilder Options { get; set; }
|
||||
|
||||
//public T CreateDB()
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
//DbContext dbContext;
|
||||
//[Attribute]
|
||||
@ -195,13 +189,17 @@ namespace Esiur.Stores.EntityCore
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal DbContextOptions Options { get; set; }
|
||||
|
||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||
{
|
||||
if (trigger == ResourceTrigger.Initialize)// SystemInitialized && DbContext != null)
|
||||
{
|
||||
|
||||
if (DbContextProvider == null)
|
||||
DbContextProvider = () => Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext;
|
||||
if (Getter == null)
|
||||
throw new Exception("Getter is not set for the store.");
|
||||
// DbContextProvider = () => Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext;
|
||||
|
||||
|
||||
ReloadModel();
|
||||
}
|
||||
@ -209,21 +207,23 @@ namespace Esiur.Stores.EntityCore
|
||||
return new AsyncReply<bool>(true);
|
||||
}
|
||||
|
||||
public void ReloadModel()
|
||||
void ReloadModel()
|
||||
{
|
||||
|
||||
TypesByName.Clear();
|
||||
TypesByType.Clear();
|
||||
|
||||
var context = DbContextProvider();// Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext;
|
||||
var context = Getter();
|
||||
|
||||
var types = context.Model.GetEntityTypes();
|
||||
foreach (var t in types)
|
||||
{
|
||||
var ti = new TypeInfo()
|
||||
var ti = new EntityTypeInfo()
|
||||
{
|
||||
Name = t.ClrType.Name,
|
||||
PrimaryKey = t.FindPrimaryKey().Properties.FirstOrDefault()?.PropertyInfo,
|
||||
Type = t
|
||||
Type = t,
|
||||
//Getter = getter
|
||||
};
|
||||
|
||||
TypesByName.Add(t.ClrType.Name, ti);
|
||||
@ -236,7 +236,7 @@ namespace Esiur.Stores.EntityCore
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
OnDestroy?.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
17
Esiur.Stores.EntityCore/EntityTypeInfo.cs
Normal file
17
Esiur.Stores.EntityCore/EntityTypeInfo.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Stores.EntityCore
|
||||
{
|
||||
struct EntityTypeInfo
|
||||
{
|
||||
public string Name;
|
||||
public IEntityType Type;
|
||||
public PropertyInfo PrimaryKey;
|
||||
// public Func<DbContext> Getter;
|
||||
}
|
||||
}
|
@ -9,10 +9,11 @@
|
||||
<Product>Esiur Entity Framework Extension</Product>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageId>Esiur.Stores.EntityCore</PackageId>
|
||||
<Version>1.0.2</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.6" />
|
||||
<PackageReference Include="System.Collections" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -34,10 +34,11 @@ using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using System.Reflection;
|
||||
using Esiur.Proxy;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Esiur.Stores.EntityCore
|
||||
{
|
||||
public class EsiurExtensionOptions : IDbContextOptionsExtension
|
||||
public class EsiurExtensionOptions : IDbContextOptionsExtension
|
||||
{
|
||||
|
||||
//public Dictionary<Type, PropertyInfo> Cache { get; } = new Dictionary<Type, PropertyInfo>();
|
||||
|
@ -23,6 +23,9 @@ SOFTWARE.
|
||||
*/
|
||||
|
||||
using Esiur.Core;
|
||||
using Esiur.Data;
|
||||
using Esiur.Misc;
|
||||
using Esiur.Proxy;
|
||||
using Esiur.Resource;
|
||||
using Esiur.Security.Permissions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -31,6 +34,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Stores.EntityCore
|
||||
@ -43,49 +47,108 @@ namespace Esiur.Stores.EntityCore
|
||||
|
||||
//}
|
||||
|
||||
public static T AddResource<T>(this DbSet<T> dbSet, object properties = null) where T : class, IResource
|
||||
=> AddResourceAsync(dbSet, properties).Wait();
|
||||
public static T AddResource<T>(this DbSet<T> dbSet, T resource) where T : class, IResource
|
||||
=> AddResourceAsync(dbSet, resource).Wait();
|
||||
|
||||
public static async AsyncReply<T> AddResourceAsync<T>(this DbSet<T> dbSet, object properties = null) where T : class, IResource
|
||||
public static async AsyncReply<T> AddResourceAsync<T>(this DbSet<T> dbSet, T resource) where T : class, IResource
|
||||
{
|
||||
var store = dbSet.GetInfrastructure().GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>().Store;
|
||||
|
||||
|
||||
var manager = store.Instance.Managers.FirstOrDefault();// > 0 ? store.Instance.Managers.First() : null;
|
||||
|
||||
//var db = dbSet.GetService<ICurrentDbContext>().Context;
|
||||
|
||||
//var resource = dbSet.GetInfrastructure().CreateResource<T>(properties);
|
||||
//var resource = Warehouse.New<T>("", options.Store, null, null, null, properties);
|
||||
var resource = await Warehouse.New<T>("", null, null, null, null, properties);
|
||||
var entity = dbSet.Add(resource);
|
||||
|
||||
var resType = typeof(T);
|
||||
var proxyType = ResourceProxy.GetProxy(resType);
|
||||
|
||||
|
||||
IResource res;
|
||||
|
||||
if (proxyType == resType)
|
||||
{
|
||||
res = resource;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = Activator.CreateInstance(proxyType) as IResource;
|
||||
var ps = Structure.FromObject(resource);
|
||||
|
||||
foreach (var p in ps)
|
||||
{
|
||||
|
||||
var mi = resType.GetMember(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (mi != null)
|
||||
{
|
||||
if (mi is PropertyInfo)
|
||||
{
|
||||
var pi = mi as PropertyInfo;
|
||||
if (pi.CanWrite)
|
||||
{
|
||||
try
|
||||
{
|
||||
pi.SetValue(res, p.Value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Global.Log(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mi is FieldInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
(mi as FieldInfo).SetValue(res, p.Value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Global.Log(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//await Warehouse.Put<T>("", null, null, null, null, properties);
|
||||
var entity = dbSet.Add((T)res);
|
||||
await entity.Context.SaveChangesAsync();
|
||||
|
||||
|
||||
var id = store.TypesByType[typeof(T)].PrimaryKey.GetValue(resource);
|
||||
|
||||
await Warehouse.Put(resource, id.ToString(), store, null, null, 0, manager);
|
||||
await Warehouse.Put(id.ToString(), res, store, null, null, 0, manager);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
public static async AsyncReply<T> CreateResourceAsync<T>(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource
|
||||
{
|
||||
var options = serviceProvider.GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>();
|
||||
//public static async AsyncReply<T> CreateResourceAsync<T>(this IServiceProvider serviceProvider, T properties = null) where T : class, IResource
|
||||
//{
|
||||
// var options = serviceProvider.GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions<T>>();
|
||||
|
||||
var resource = await Warehouse.New<T>("", options.Store, null, null, null, properties);
|
||||
// var resource = await Warehouse.New<T>("", options.Store, null, null, null, properties);
|
||||
|
||||
resource.Instance.Managers.AddRange(options.Store.Instance.Managers.ToArray());
|
||||
// resource.Instance.Managers.AddRange(options.Store.Instance.Managers.ToArray());
|
||||
|
||||
return resource;
|
||||
}
|
||||
// return resource;
|
||||
//}
|
||||
|
||||
public static T CreateResource<T>(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource
|
||||
=> CreateResourceAsync<T>(serviceProvider, properties).Wait();
|
||||
//public static T CreateResource<T>(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource
|
||||
// => CreateResourceAsync<T>(serviceProvider, properties).Wait();
|
||||
|
||||
public static DbContextOptionsBuilder UseEsiur(this DbContextOptionsBuilder optionsBuilder,
|
||||
//DbContext context,
|
||||
string name = null,
|
||||
IResource parent = null,
|
||||
IPermissionsManager manager = null,
|
||||
Func<DbContext> dbContextProvider = null
|
||||
EntityStore store,
|
||||
Func<DbContext> getter = null
|
||||
|
||||
//IServiceCollection services = null
|
||||
//string name = null,
|
||||
//IResource parent = null,
|
||||
//IPermissionsManager manager = null,
|
||||
//Func<DbContext> dbContextProvider = null
|
||||
)
|
||||
{
|
||||
var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
|
||||
@ -93,10 +156,9 @@ namespace Esiur.Stores.EntityCore
|
||||
if (extension == null)
|
||||
{
|
||||
|
||||
var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
|
||||
//var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
|
||||
store.Options = optionsBuilder.Options;
|
||||
extension = new EsiurExtensionOptions(store);
|
||||
//store.Options = optionsBuilder;
|
||||
//store.DbContext = context;
|
||||
}
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
@ -105,34 +167,34 @@ namespace Esiur.Stores.EntityCore
|
||||
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseEsiur<TContext>(
|
||||
this DbContextOptionsBuilder<TContext> optionsBuilder,
|
||||
//DbContext context,
|
||||
string name = null,
|
||||
IResource parent = null,
|
||||
IPermissionsManager manager = null,
|
||||
Func<DbContext> dbContextProvider = null)
|
||||
where TContext : DbContext
|
||||
{
|
||||
//public static DbContextOptionsBuilder<TContext> UseEsiur<TContext>(
|
||||
// this DbContextOptionsBuilder<TContext> optionsBuilder,
|
||||
// //DbContext context,
|
||||
// string name = null,
|
||||
// IResource parent = null,
|
||||
// IPermissionsManager manager = null,
|
||||
// Func<DbContext> dbContextProvider = null)
|
||||
// where TContext : DbContext
|
||||
//{
|
||||
|
||||
|
||||
var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
|
||||
// var extension = optionsBuilder.Options.FindExtension<EsiurExtensionOptions>();
|
||||
|
||||
if (extension == null)
|
||||
{
|
||||
var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
|
||||
extension = new EsiurExtensionOptions(store);
|
||||
//store.Options = optionsBuilder;
|
||||
//store.Options = extension;
|
||||
//store.DbContext = context;
|
||||
}
|
||||
// if (extension == null)
|
||||
// {
|
||||
// var store = Warehouse.New<EntityStore>(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }).Wait();
|
||||
// extension = new EsiurExtensionOptions(store);
|
||||
// //store.Options = optionsBuilder;
|
||||
// //store.Options = extension;
|
||||
// //store.DbContext = context;
|
||||
// }
|
||||
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
// ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
// return optionsBuilder;
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
|
||||
namespace Esiur.Stores.EntityCore
|
||||
{
|
||||
public class EsiurProxyRewrite : IModelFinalizingConvention
|
||||
public class EsiurProxyRewrite : IModelFinalizingConvention
|
||||
{
|
||||
private static readonly MethodInfo _createInstance
|
||||
= typeof(EsiurProxyRewrite).GetTypeInfo().GetDeclaredMethod(nameof(EsiurProxyRewrite.CreateInstance));
|
||||
@ -79,7 +79,7 @@ namespace Esiur.Stores.EntityCore
|
||||
var obj = Warehouse.New(entityType.ClrType).Wait() as EntityResource;//, "", options.Store, null, manager);
|
||||
//obj._PrimaryId = id;
|
||||
options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id);
|
||||
Warehouse.Put(obj, id.ToString(), options.Store, null, null, 0, manager).Wait();
|
||||
Warehouse.Put(id.ToString(), obj, options.Store, null, null, 0, manager).Wait();
|
||||
|
||||
// obj.Instance.IntVal = id;//.Variables.Add("eid", id);
|
||||
|
||||
|
Reference in New Issue
Block a user