diff --git a/Esiur.Stores.EntityCore/EntityStore.cs b/Esiur.Stores.EntityCore/EntityStore.cs index cf2f8fc..7e56ebb 100644 --- a/Esiur.Stores.EntityCore/EntityStore.cs +++ b/Esiur.Stores.EntityCore/EntityStore.cs @@ -33,6 +33,8 @@ using Esiur.Proxy; using System.Linq; using Microsoft.EntityFrameworkCore.Metadata; using System.Reflection; +using Esiur.Security.Authority; +using System.Collections; namespace Esiur.Stores.EntityCore; public class EntityStore : IStore @@ -63,30 +65,42 @@ public class EntityStore : IStore var id = Convert.ChangeType(p[1], ti.PrimaryKey.PropertyType); // Get db - var db = Getter(); - var res = db.Find(ti.Type.ClrType, id); - - if (res == null) + using (var db = Getter()) { - return new AsyncReply(null); - //var rt = new AsyncReply(); - //rt.TriggerError(new AsyncException(ErrorType.Management, - // (ushort)ExceptionCode.ResourceNotFound, "Resource not found.")); - //return rt; + var res = db.Find(ti.Type.ClrType, id) as IResource; + + + if (res == null) + { + return new AsyncReply(null); + + //var rt = new AsyncReply(); + //rt.TriggerError(new AsyncException(ErrorType.Management, + // (ushort)ExceptionCode.ResourceNotFound, "Resource not found.")); + //return rt; + } + + + // load navigation properties + var ent = db.Entry(res); + + foreach (var rf in ent.References) + { + rf.Load(); + } + + foreach(var col in ent.Collections) + { + col.Load(); + } + + //var refs = ent.References.ToList(); + + db.Dispose(); + + return new AsyncReply(res); } - - // load navigation properties - var ent = db.Entry(res); - foreach (var rf in ent.References) - rf.Load(); - - foreach(var nav in ent.Navigations) - nav.Load(); - - //var refs = ent.References.ToList(); - - return new AsyncReply(res as IResource); } public AsyncReply Put(IResource resource) diff --git a/Esiur.Stores.EntityCore/Esiur.Stores.EntityCore.csproj b/Esiur.Stores.EntityCore/Esiur.Stores.EntityCore.csproj index 6fab6bb..1567ddd 100644 --- a/Esiur.Stores.EntityCore/Esiur.Stores.EntityCore.csproj +++ b/Esiur.Stores.EntityCore/Esiur.Stores.EntityCore.csproj @@ -22,7 +22,7 @@ - + diff --git a/Esiur.Stores.EntityCore/EsiurExtensions.cs b/Esiur.Stores.EntityCore/EsiurExtensions.cs index 35661d8..cdee63d 100644 --- a/Esiur.Stores.EntityCore/EsiurExtensions.cs +++ b/Esiur.Stores.EntityCore/EsiurExtensions.cs @@ -47,6 +47,10 @@ public static class EsiurExtensions //} + public static DbSet SetByType(this DbContext context, Type t) + { + return (DbSet)context.GetType().GetMethod("Set").MakeGenericMethod(t).Invoke(context, new object[0]); + } public static T AddResource(this DbSet dbSet, T resource) where T : class, IResource => AddResourceAsync(dbSet, resource).Wait(); diff --git a/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs b/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs index 316505b..5762947 100644 --- a/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs +++ b/Esiur.Stores.EntityCore/EsiurProxyRewrite.cs @@ -61,8 +61,10 @@ public class EsiurProxyRewrite : IModelFinalizingConvention var cache = options.Store.GetById(entityType.ClrType, id); - if (cache != null) + if (cache != null && cache.Instance != null) + { return cache; + } if (Codec.ImplementsInterface(entityType.ClrType, typeof(IResource))) { diff --git a/Esiur/Data/AutoList.cs b/Esiur/Data/AutoList.cs index 18a5ccc..04b68ec 100644 --- a/Esiur/Data/AutoList.cs +++ b/Esiur/Data/AutoList.cs @@ -97,7 +97,7 @@ public class AutoList : IEnumerable, ICollection, ICollection /// Create a new instance of AutoList /// /// State object to be included when an event is raised. - public AutoList(ST state) + public AutoList(ST state = default(ST)) { State = state; #if NETSTANDARD diff --git a/Esiur/Data/Codec.cs b/Esiur/Data/Codec.cs index 501fea1..ac7cfe2 100644 --- a/Esiur/Data/Codec.cs +++ b/Esiur/Data/Codec.cs @@ -203,14 +203,19 @@ public static class Codec // Special [typeof(object[])] = DataSerializer.ListComposer,// DataSerializer.ListComposerFromArray, [typeof(List)] = DataSerializer.ListComposer,// DataSerializer.ListComposerFromList, + [typeof(VarList)] = DataSerializer.ListComposer,// DataSerializer.ListComposerFromList, [typeof(IResource[])] = DataSerializer.ResourceListComposer,// (value, con) => (TransmissionTypeIdentifier.ResourceList, DC.ToBytes((decimal)value)), [typeof(IResource?[])] = DataSerializer.ResourceListComposer,// (value, con) => (TransmissionTypeIdentifier.ResourceList, DC.ToBytes((decimal)value)), [typeof(List)] = DataSerializer.ResourceListComposer, //(value, con) => (TransmissionTypeIdentifier.ResourceList, DC.ToBytes((decimal)value)), [typeof(List)] = DataSerializer.ResourceListComposer, //(value, con) => (TransmissionTypeIdentifier.ResourceList, DC.ToBytes((decimal)value)), + [typeof(VarList)] = DataSerializer.ResourceListComposer, //(value, con) => (TransmissionTypeIdentifier.ResourceList, DC.ToBytes((decimal)value)), + [typeof(VarList)] = DataSerializer.ResourceListComposer, //(value, con) => (TransmissionTypeIdentifier.ResourceList, DC.ToBytes((decimal)value)), [typeof(IRecord[])] = DataSerializer.RecordListComposer,// (value, con) => (TransmissionTypeIdentifier.RecordList, DC.ToBytes((decimal)value)), [typeof(IRecord?[])] = DataSerializer.RecordListComposer,// (value, con) => (TransmissionTypeIdentifier.RecordList, DC.ToBytes((decimal)value)), [typeof(List)] = DataSerializer.RecordListComposer, //(value, con) => (TransmissionTypeIdentifier.RecordList, DC.ToBytes((decimal)value)), [typeof(List)] = DataSerializer.RecordListComposer, //(value, con) => (TransmissionTypeIdentifier.RecordList, DC.ToBytes((decimal)value)), + [typeof(VarList)] = DataSerializer.RecordListComposer, //(value, con) => (TransmissionTypeIdentifier.RecordList, DC.ToBytes((decimal)value)), + [typeof(VarList)] = DataSerializer.RecordListComposer, //(value, con) => (TransmissionTypeIdentifier.RecordList, DC.ToBytes((decimal)value)), [typeof(Map)] = DataSerializer.MapComposer, [typeof(Map)] = DataSerializer.MapComposer, [typeof(Map)] = DataSerializer.MapComposer, @@ -297,7 +302,7 @@ public static class Codec else if (type.IsGenericType) { var genericType = type.GetGenericTypeDefinition(); - if (genericType == typeof(List<>)) + if (genericType == typeof(List<>) || genericType == typeof(VarList<>)) { var args = type.GetGenericArguments(); //if (Composers.ContainsKey(args[0])) diff --git a/Esiur/Data/DataSerializer.cs b/Esiur/Data/DataSerializer.cs index 754c6ce..91aabfb 100644 --- a/Esiur/Data/DataSerializer.cs +++ b/Esiur/Data/DataSerializer.cs @@ -317,6 +317,11 @@ public static class DataSerializer var resource = (IResource)value; var rt = new byte[4]; + if (resource.Instance == null || resource.Instance.IsDestroyed) + { + return (TransmissionTypeIdentifier.Null, new byte[0]); + } + if (Codec.IsLocalResource(resource, connection)) { @@ -327,9 +332,13 @@ public static class DataSerializer } else { + //rt.Append((value as IResource).Instance.Template.ClassId, (value as IResource).Instance.Id); connection.cache.Add(value as IResource, DateTime.UtcNow); + + Console.WriteLine("Adding to cache " + resource.Instance.Id); + fixed (byte* ptr = rt) *((uint*)ptr) = resource.Instance.Id; diff --git a/Esiur/Data/RepresentationType.cs b/Esiur/Data/RepresentationType.cs index 5e0c6a5..842f17f 100644 --- a/Esiur/Data/RepresentationType.cs +++ b/Esiur/Data/RepresentationType.cs @@ -232,7 +232,7 @@ namespace Esiur.Data else if (type.IsGenericType) { var genericType = type.GetGenericTypeDefinition(); - if (genericType == typeof(List<>)) + if (genericType == typeof(List<>) || genericType == typeof(VarList<>)) { var args = type.GetGenericArguments(); if (args[0] == typeof(object)) diff --git a/Esiur/Data/VarList.cs b/Esiur/Data/VarList.cs index 7d6eba0..574374d 100644 --- a/Esiur/Data/VarList.cs +++ b/Esiur/Data/VarList.cs @@ -8,7 +8,7 @@ using System.Text; namespace Esiur.Data { - public class VarList : IEnumerable, ICollection, ICollection + public class VarList : IEnumerable, ICollection, ICollection { string propertyName; IResource resource; @@ -21,6 +21,11 @@ namespace Esiur.Data this.propertyName = propertyName; } + public VarList() + { + Console.WriteLine("New varlist"); + } + public int Count => list.Count; public bool IsReadOnly => false; diff --git a/Esiur/Net/IIP/DistributedConnectionProtocol.cs b/Esiur/Net/IIP/DistributedConnectionProtocol.cs index 7169af9..1e2bb6e 100644 --- a/Esiur/Net/IIP/DistributedConnectionProtocol.cs +++ b/Esiur/Net/IIP/DistributedConnectionProtocol.cs @@ -598,6 +598,8 @@ partial class DistributedConnection { // reply failed //SendParams(0x80, r.Instance.Id, r.Instance.Age, r.Instance.Serialize(false, this)); + Console.WriteLine("Not found " + resourceId); + SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound); } }); diff --git a/Esiur/Resource/Instance.cs b/Esiur/Resource/Instance.cs index 6097624..702e96d 100644 --- a/Esiur/Resource/Instance.cs +++ b/Esiur/Resource/Instance.cs @@ -704,6 +704,8 @@ public class Instance get { return store; } } + public bool IsDestroyed { get; private set; } + /// /// List of children. /// @@ -1009,6 +1011,7 @@ public class Instance private void Resource_OnDestroy(object sender) { + IsDestroyed = true; Destroyed?.Invoke((IResource)sender); } } diff --git a/Esiur/Resource/Warehouse.cs b/Esiur/Resource/Warehouse.cs index ad9be4b..0a108ae 100644 --- a/Esiur/Resource/Warehouse.cs +++ b/Esiur/Resource/Warehouse.cs @@ -914,6 +914,8 @@ public static class Warehouse resource.Destroy(); + resource.Instance = null; + return true; } }