Переглянути джерело

Fix serialization of original values for unserialisable properties. Updated filter to not longe ruse Expressions.

Kenric Nugteren 6 місяців тому
батько
коміт
bd1261a5f6

+ 2 - 135
InABox.Core/CoreUtils.cs

@@ -18,8 +18,6 @@ using Newtonsoft.Json.Linq;
 using System.Runtime.CompilerServices;
 using System.Data.Common;
 
-//using Serialize.Linq.Serializers;
-
 namespace InABox.Core
 {
     public enum DatabaseProvider
@@ -1108,65 +1106,6 @@ namespace InABox.Core
             return lists.ToArray();
         }
 
-        //public static IEnumerable<Assembly> GetReferencingAssemblies(string assemblyName)
-        //{
-        //	var assemblies = new List<Assembly>();
-        //	var dependencies = DependencyContext.Default.RuntimeLibraries;
-        //	foreach (var library in dependencies)
-        //	{
-        //		if (IsCandidateLibrary(library, assemblyName))
-        //		{
-        //			var assembly = Assembly.Load(new AssemblyName(library.Name));
-        //			assemblies.Add(assembly);
-        //		}
-        //	}
-        //	return assemblies;
-        //}
-
-        //private static bool IsCandidateLibrary(RuntimeLibrary library, assemblyName)
-        //{
-        //	return library.Name == (assemblyName)
-        //		|| library.Dependencies.Any(d => d.Name.StartsWith(assemblyName));
-        //}
-
-        //public static IEnumerable<Assembly> AssemblyList(Expression<Func<Type,bool>> Predicate)
-        //{
-        //	Func<Type, bool> lambda = Predicate.Compile();
-
-        //	List<Assembly> assemblies = new List<Assembly>();
-
-        //	IEnumerable<Assembly> allassemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).ToArray();
-        //	foreach (Assembly assembly in allassemblies)
-        //	{
-        //		IEnumerable<Type> types = CoreUtils.TypeList(
-        //			new Assembly[] { assembly },
-        //			Predicate
-        //		);
-        //		if (types.Count() > 0)
-        //			assemblies.Add(assembly);
-        //	}
-        //	return assemblies;
-        //}
-
-        //public static string SerializeExpression<T>(Expression obj)
-        //{
-        //	JsonSerializerSettings _settings;
-        //	var defaultSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects };
-        //	defaultSettings.Converters.Add(new ExpressionJsonConverter(typeof(T)));
-        //	_settings = defaultSettings;
-        //	return Serialization.Serialize(obj, _settings);
-        //}
-
-        //public static Expression DeserializeExpression<T>(string json)
-        //{
-        //	JsonSerializerSettings _settings;
-        //	var defaultSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects };
-        //	defaultSettings.Converters.Add(new ExpressionJsonConverter(typeof(T)));
-        //	_settings = defaultSettings;
-        //	return Serialization.Deserialize<Expression>(json, _settings);
-        //}
-
-
         /// <summary>
         ///     [ <c>public static object GetDefault(this Type type)</c> ]
         ///     <para></para>
@@ -1683,47 +1622,23 @@ namespace InABox.Core
 
         public static Filter<T> LinkValid<T>(this Filter<T> filter, Guid entityID = default)
         {
-            var mExp = filter.Expression as MemberExpression;
-            if (mExp == null)
-                throw new ArgumentException("Filter expression is not a MemberExpression");
-
-            var idExp = Expression.PropertyOrField(mExp, "ID");
-            var deletedExp = Expression.PropertyOrField(mExp, "Deleted");
-
-            filter.Expression = idExp;
+            filter.Property = filter.Property + ".ID";
             if (entityID != Guid.Empty)
                 filter.IsEqualTo(entityID);
             else
                 filter.IsNotEqualTo(Guid.Empty);
 
-            var delFilter = new Filter<T>();
-            delFilter.Expression = deletedExp;
-            delFilter.IsEqualTo(Guid.Empty);
-            filter.And(delFilter);
-
             return filter.Parent ?? filter;
         }
 
         public static Filter<T> NotLinkValid<T>(this Filter<T> filter)
         {
-            var mExp = filter.Expression as MemberExpression;
-            if (mExp == null)
-                throw new ArgumentException("Filter expression is not a MemberExpression");
-
             filter.All();
 
             var subFilter = new Filter<T>();
 
-            var idExp = Expression.PropertyOrField(mExp, "ID");
-            var deletedExp = Expression.PropertyOrField(mExp, "Deleted");
-
-            subFilter.Expression = idExp;
+            subFilter.Property = filter.Property + ".ID";
             subFilter.IsEqualTo(Guid.Empty);
-
-            var delFilter = new Filter<T>();
-            delFilter.Expression = deletedExp;
-            delFilter.IsNotEqualTo(Guid.Empty);
-            subFilter.Or(delFilter);
             
             filter.And(subFilter);
             return filter.Parent ?? filter;
@@ -2186,46 +2101,6 @@ namespace InABox.Core
 
             result["Type"] = t.EntityName();
             return JsonConvert.SerializeObject(result);
-
-            //ExpressionSerializer ser = new ExpressionSerializer(new Serialize.Linq.Serializers.JsonSerializer(),new Serialize.Linq.Factories.FactorySettings() { UseRelaxedTypeNames=true } );
-            //String result = ser.SerializeText(expression);
-            //return result;
-
-            //if (expression.NodeType == ExpressionType.MemberAccess)
-            //{
-            //    MemberExpression memberExpression = expression as MemberExpression;
-            //    MemberExpression memberExpressionOrg = memberExpression as MemberExpression;
-
-            //    string Path = "";
-            //    while (memberExpression.Expression.NodeType == ExpressionType.MemberAccess)
-            //    {
-            //        var propInfo = memberExpression.Expression
-            //            .GetType().GetTypeInfo().GetProperty("Member");
-            //        var propValue = propInfo.GetValue(memberExpression.Expression, null)
-            //            as PropertyInfo;
-            //        Path = propValue.Name + "." + Path;
-
-            //        memberExpression = memberExpression.Expression as MemberExpression;
-            //    }
-            //    if (includetype)
-            //        return t.FullName + " => " + Path + memberExpressionOrg.Member.Name;
-            //    else
-            //        return Path + memberExpressionOrg.Member.Name;
-            //}
-            //else if (expression.NodeType == ExpressionType.Index)
-            //{
-            //    if (includetype)
-            //        return t.FullName + " => " + expression.ToString();
-            //    else
-            //        return expression.ToString();
-            //}
-            //else
-            //{
-            //    if (includetype)
-            //        return t.FullName + " => " + expression.ToString();
-            //    else
-            //        return expression.ToString();
-            //}
         }
 
         public static Expression StringToExpression(string expression)
@@ -2238,14 +2113,6 @@ namespace InABox.Core
                 return CreateMemberExpression(t, member);
             else
                 return Expression.Parameter(t, "x");
-
-            //ExpressionSerializer ser = new ExpressionSerializer(new Serialize.Linq.Serializers.JsonSerializer(), new Serialize.Linq.Factories.FactorySettings() { UseRelaxedTypeNames = true });
-            //Expression result = ser.DeserializeText(expression);
-            //return result;
-
-            //String[] comps = expression.Split(new String[] { " => " }, StringSplitOptions.None);
-            //Type type = comps.Length > 1 ? CoreUtils.GetEntity(comps[0]) : t;
-            //return CreateExpression(type, comps[comps.Length - 1]);
         }
 
         public static Expression<Func<T, object?>> CreateLambdaExpression<T>(string column)

+ 1 - 2
InABox.Core/DataModel/DataModel.cs

@@ -380,8 +380,7 @@ namespace InABox.Core
             var parentFilter = GetTableFilter<TParent>(relation.ParentTable, requiredQueries);
             var subQuery = new SubQuery<TParent>(parentFilter, new Column<TParent>(relation.ParentColumnAsPropertyName()));
 
-            var filter = new Filter<TChild>();
-            filter.Expression = CoreUtils.CreateMemberExpression(typeof(TChild), relation.ChildColumnAsPropertyName());
+            var filter = new Filter<TChild>(relation.ChildColumnAsPropertyName());
             filter.Operator = Operator.InQuery;
             filter.Value = subQuery;
 

+ 17 - 24
InABox.Core/Query/Column.cs

@@ -80,11 +80,18 @@ namespace InABox.Core
         {
             get
             {
-                if (Expression is null)
-                    throw new Exception($"Expression [{Property}] may not be null");
-                if (Expression is IndexExpression)
-                    return PropertyDefinition.PropertyType;
-                return Expression.Type;
+                return PropertyDefinition.PropertyType;
+            }
+        }
+
+        private string _property;
+        public string Property
+        {
+            get => _property;
+            set
+            {
+                _property = value;
+                _propertyDefinition = null;
             }
         }
 
@@ -98,14 +105,11 @@ namespace InABox.Core
             }
             set
             {
+                _property = value.Name;
                 _propertyDefinition = value;
             }
         }
 
-        public string Property { get; private set; }
-
-        public Expression Expression { get; private set; }
-
         public bool IsEqualTo(string name) => 
             !name.IsNullOrWhiteSpace() && Property.Equals(name);
         public bool IsEqualTo(Column<T> column) =>
@@ -116,29 +120,18 @@ namespace InABox.Core
 
         public Column(IProperty property)
         {
-            Property = property.Name;
-            Expression = property.Expression();
-            PropertyDefinition = property;
+            _property = property.Name;
+            _propertyDefinition = property;
         }
 
         public Column(Expression<Func<T, object?>> expression)
         {
-            Property = CoreUtils.GetFullPropertyName(expression, ".");
-            Expression = CoreUtils.ExtractMemberExpression(expression);
+            _property = CoreUtils.GetFullPropertyName(expression, ".");
         }
 
         public Column(string property)
         {
-            Property = property;
-
-            var iprop = DatabaseSchema.Property(typeof(T), property);
-            if (iprop != null)
-            {
-                PropertyDefinition = iprop;
-                Expression = iprop.Expression();
-            }
-            else
-                Expression = CoreUtils.CreateMemberExpression(typeof(T), property);
+            _property = property;
         }
 
         public Column<TNew> Cast<TNew>()

+ 78 - 202
InABox.Core/Query/Filter.cs

@@ -220,7 +220,9 @@ namespace InABox.Core
 
     public interface IFilter : ISerializeBinary
     {
-        Expression Expression { get; set; }
+        string Property { get; set; }
+        Type Type { get; }
+
         Operator Operator { get; set; }
         object? Value { get; set; }
 
@@ -381,8 +383,45 @@ namespace InABox.Core
 
     }
 
-    public class Filter<T> : SerializableExpression<T>, IFilter
+    public class Filter<T> : IFilter
     {
+        public Type Type => PropertyDefinition?.PropertyType ?? typeof(object);
+
+        private string _property;
+        public string Property
+        {
+            get => _property;
+            set
+            {
+                _property = value;
+                _propertyDefinition = null;
+            }
+        }
+
+        private IProperty? _propertyDefinition;
+        public IProperty? PropertyDefinition
+        {
+            get
+            {
+                if (Property.IsNullOrWhiteSpace())
+                {
+                    return null;
+                }
+                else
+                {
+                    _propertyDefinition ??= DatabaseSchema.PropertyStrict(typeof(T), Property);
+                    return _propertyDefinition;
+                }
+            }
+            set
+            {
+                _propertyDefinition = value;
+                if(value != null)
+                {
+                    Property = value.Name;
+                }
+            }
+        }
         
         public Filter<T>? Parent { get; set; }
 
@@ -585,73 +624,42 @@ namespace InABox.Core
 
         #endregion
 
-        //public override void GetObjectData(SerializationInfo info, StreamingContext context)
-        //{
-        //	base.GetObjectData(info, context);
-
-        //	if (info != null)
-        //		info.AddValue("ErrorMessage", this.ErrorMessage);
-        //}
-
-
-        public Filter<T1> Attach<T1>(Expression<Func<T1, object>> anchor)
-        {
-            var result = new Filter<T1>();
-            result.Expression = CoreUtils.ConvertExpression(typeof(T), Expression, typeof(T1), anchor);
-            result.Operator = Operator;
-            result.Value = Value;
-            foreach (var and in Ands)
-                and.Attach(anchor);
-            foreach (var or in Ors)
-                or.Attach(anchor);
-            return result;
-        }
-        
         #region Constructors
 
         public Filter()
         {
             Ands = new List<Filter<T>>();
             Ors = new List<Filter<T>>();
+
+            _property = "";
         }
 
-        public Filter(Column<T> column): base(column.Expression)
+        public Filter(Column<T> column) : this()
         {
-            Ands = new List<Filter<T>>();
-            Ors = new List<Filter<T>>();
+            _property = column.Property;
+            _propertyDefinition = column.PropertyDefinition;
         }
-        
-        //public Filter(object expression) : base()
-        //{
-        //	Ands = new List<Filter<T>>();
-        //	Ors = new List<Filter<T>>();
-        //}
 
-        public Filter(Expression<Func<T, object?>> expression) : base(expression)
+        public Filter(Expression<Func<T, object?>> expression) : this()
         {
-            Ands = new List<Filter<T>>();
-            Ors = new List<Filter<T>>();
+            _property = CoreUtils.GetFullPropertyName(expression, ".");
         }
 
-        public Filter(string property) : base(property)
+        public Filter(IProperty property) : this()
         {
-            Ands = new List<Filter<T>>();
-            Ors = new List<Filter<T>>();
+            _property = property.Name;
+            _propertyDefinition = property;
         }
 
-        public Filter(string property, Operator op, object value) : base(property)
+        public Filter(string property) : this()
         {
-            Ands = new List<Filter<T>>();
-            Ors = new List<Filter<T>>();
-            Operator = op;
-            Value = value;
+            _property = property;
         }
 
-        public Filter(SerializationInfo info, StreamingContext context)
+        public Filter(string property, Operator op, object value) : this(property)
         {
-            Ands = new List<Filter<T>>();
-            Ors = new List<Filter<T>>();
-            Deserialize(info, context);
+            Operator = op;
+            Value = value;
         }
 
         public static explicit operator Filter<T>?(Filter<Entity>? v)
@@ -677,13 +685,10 @@ namespace InABox.Core
         public Filter<TNew> Cast<TNew>()
             where TNew : T
         {
-            var prop = "";
-            if (CoreUtils.TryFindMemberExpression(Expression, out var mexp))
-            {
-                prop = CoreUtils.GetFullPropertyName(mexp, ".");
-            }
+            var filter = new Filter<TNew>();
+            filter._property = _property;
+            filter._propertyDefinition = _propertyDefinition;
 
-            var filter = new Filter<TNew>(prop);
             filter.Operator = Operator;
             filter.Value = Value;
             filter.IsNot = IsNot;
@@ -1046,8 +1051,7 @@ namespace InABox.Core
             {
                 CoreUtils.TryFindMemberExpression(expression.Body, out var me);
 
-                var filter = new Filter<T>();
-                filter.Expression = me;
+                var filter = new Filter<T>(CoreUtils.MemberExpressionToString(me));
                 filter.Operator = includes.Equals(ListOperator.Includes) ? Operator.IsEqualTo : Operator.IsNotEqualTo;
                 filter.Value = value;
 
@@ -1116,130 +1120,6 @@ namespace InABox.Core
 
         #endregion
 
-        #region Expression Functions
-
-        public Expression<Func<T, bool>> AsExpression()
-        {
-            var expression = Expression;
-            if (expression is null)
-                throw new Exception("Expression is null");
-
-            var param = Expression.Parameter(typeof(T), "x");
-            //Expression expr = param;
-
-            Expression constant = Expression.Constant(null, typeof(object));
-
-            //expr = Expression;
-
-            if (Value != null)
-            {
-                var valType = Value.GetType();
-
-                var propType = expression.Type;
-
-                if (valType.Equals(typeof(string)) && propType.Equals(typeof(Guid)))
-                    constant = Expression.Constant(Guid.Parse(Value.ToString()), propType);
-                else if (valType.Equals(typeof(string)) && propType.Equals(typeof(bool)))
-                    constant = Expression.Constant(bool.Parse(Value.ToString()), propType);
-                else if (valType.Equals(typeof(string)) && propType.Equals(typeof(TimeSpan)))
-                    constant = Expression.Constant(TimeSpan.Parse(Value.ToString()), propType);
-                else if (valType.Equals(typeof(string)) && propType.Equals(typeof(ScriptType)))
-                    constant = Expression.Constant((ScriptType)int.Parse(Value.ToString()), propType);
-                //else if (valType.Equals(typeof(String)) && propType.Equals(typeof(DateTime)))
-                //    constant = Expression.Constant(JsonConvert.DeserializeObject<DateTime>(Value.ToString()), propType);
-
-                else
-                    try
-                    {
-                        constant = Expression.Constant(Value, expression.Type);
-                        //constant = Expression.Constant(Value, propType);
-                    }
-                    catch
-                    {
-                        var val = Value;
-
-                        if (!propType.Equals(valType) && !(val is FilterConstant))
-                        {
-                            val = CoreUtils.ChangeType(val, propType);
-                        }
-                        constant = Expression.Constant(val, propType);
-                    }
-            }
-
-            Expression final = Operator switch
-            {
-                Operator.IsEqualTo => Expression.Equal(expression, constant),
-                Operator.IsNotEqualTo => Expression.NotEqual(expression, constant),
-                Operator.IsGreaterThan => Expression.GreaterThan(expression, constant),
-                Operator.IsGreaterThanOrEqualTo => Expression.GreaterThanOrEqual(expression, constant),
-                Operator.IsLessThan => Expression.LessThan(expression, constant),
-                Operator.IsLessThanOrEqualTo => Expression.LessThanOrEqual(expression, constant),
-                Operator.Contains => CreateContainsExpression(expression, constant),
-                _ => throw new Exception("Invalid Operator"),
-            };
-            var result = Expression.Lambda<Func<T, bool>>(final, param);
-            if (Ands != null)
-                foreach (var filter in Ands)
-                    result = result.And(filter.AsExpression());
-            if (Ors != null)
-                foreach (var filter in Ors)
-                    result = result.Or(filter.AsExpression());
-
-            return result;
-        }
-
-        private Expression CreateContainsExpression(Expression expr, Expression constant)
-        {
-            var parameterExp = Expression.Parameter(typeof(string), "type");
-            var method = typeof(string).GetTypeInfo().GetMethod("Contains", new[] { typeof(string) });
-            var containsMethodExp = Expression.Call(expr, method, constant);
-            return containsMethodExp;
-        }
-
-        #endregion
-
-        #region Serialization
-
-        public override void Serialize(SerializationInfo info, StreamingContext context)
-        {
-            info.AddValue("Operator", Operator.ToString());
-            info.AddValue("Value", Value);
-            info.AddValue("IsNot", IsNot);
-            if (Ands.Count > 0)
-                info.AddValue("Ands", Ands, typeof(List<Filter<T>>));
-            if (Ors.Count > 0)
-                info.AddValue("Ors", Ors, typeof(List<Filter<T>>));
-        }
-
-        public override void Deserialize(SerializationInfo info, StreamingContext context)
-        {
-            //Expression = CoreUtils.StringToExpression(typeof(T), (String)info.GetValue("Expression", typeof(String)));
-
-            Operator = (Operator)Enum.Parse(typeof(Operator), (string)info.GetValue("Operator", typeof(string)));
-            Value = info.GetValue("Value", typeof(object));
-            IsNot = info.GetBoolean("IsNot");
-
-            try
-            {
-                Ands = (List<Filter<T>>)info.GetValue("Ands", typeof(List<Filter<T>>));
-            }
-            catch
-            {
-                Ands = new List<Filter<T>>();
-            }
-
-            try
-            {
-                Ors = (List<Filter<T>>)info.GetValue("Ors", typeof(List<Filter<T>>));
-            }
-            catch
-            {
-                Ors = new List<Filter<T>>();
-            }
-        }
-
-        #endregion
-
         #region Binary Serialisation
 
         private enum ValueType
@@ -1615,7 +1495,10 @@ namespace InABox.Core
 
         public void SerializeBinary(CoreBinaryWriter writer)
         {
-            writer.SerialiseExpression(typeof(T), Expression, false);
+            // For compatability purposes when redesigning system to no longer use Serializable Expression.
+            writer.Write((byte)0);
+
+            writer.Write(Property);
             if (IsNot)
             {
                 writer.Write((byte)Operator.Not);
@@ -1639,7 +1522,10 @@ namespace InABox.Core
 
         public void DeserializeBinary(CoreBinaryReader reader)
         {
-            Expression = reader.DeserialiseExpression(typeof(T));
+            // For compatability purposes when redesigning system to no longer use Serializable Expression.
+            reader.ReadByte();
+
+            Property = reader.ReadString();
 
             Operator = (Operator)reader.ReadByte();
             if(Operator == Operator.Not)
@@ -1650,8 +1536,8 @@ namespace InABox.Core
 
             var val = DeserializeValue(reader);
             var type = (Operator == Operator.InList || Operator == Operator.NotInList)
-                ? Expression.Type.MakeArrayType()
-                : Expression.Type;
+                ? Type.MakeArrayType()
+                : Type;
             Value = CoreUtils.ChangeType(val, type);
 
             Ands.Clear();
@@ -1718,23 +1604,15 @@ namespace InABox.Core
             {
                 result = "None";
             }
-            else if (Expression != null)
+            else if (Property != null)
             {
                 var value = "null";
                 if (Value != null)
                 {
                     value = ValueToString(Value);
                 }
-
-                string prop;
-                if (CoreUtils.TryFindMemberExpression(Expression, out var mexp))
-                    prop = CoreUtils.GetFullPropertyName(mexp, "/");
-                else
-                    prop = Expression.ToString();
-
-
                 result = string.Format("(" + operators[Operator] + ")",
-                    prop,
+                    Property,
                     value
                 );
             }
@@ -1774,7 +1652,7 @@ namespace InABox.Core
         public IEnumerable<string> ColumnNames()
         {
             List<String> result = new List<string>();
-            result.Add(CoreUtils.ExpressionToString(typeof(T), Expression));
+            result.Add(Property);
             foreach (var and in Ands)
                 result.AddRange(and.ColumnNames());
             foreach (var or in Ors)
@@ -2019,11 +1897,10 @@ namespace InABox.Core
                 writer.WriteNull();
                 return;
             }
-            
-            var property = filter.Expression;
+
             //MethodInfo mi = value.GetType().GetTypeInfo().GetMethod("ExpressionToString");
             //String prop = mi.Invoke(value, new object[] { property, true }) as String;
-            var prop = CoreUtils.ExpressionToString(value.GetType().GenericTypeArguments[0], property, true);
+            var prop = filter.Property;
 
             var op = filter.Operator;
             var val = filter.Value;
@@ -2060,7 +1937,7 @@ namespace InABox.Core
             else
             {
                 writer.WritePropertyName("Value");
-                var valType = val == null ? property.Type : val.GetType();
+                var valType = val == null ? filter.Type : val.GetType();
                 if (valType.IsArray)
                 {
                     writer.WriteStartArray();
@@ -2162,7 +2039,6 @@ namespace InABox.Core
             var result = (Activator.CreateInstance(finaltype) as IFilter)!;
 
             var prop = data["Expression"].ToString();
-            var exp = CoreUtils.StringToExpression(prop);
             var op = (Operator)int.Parse(data["Operator"].ToString());
 
             if(data.TryGetValue("IsNot", out var isNotValue) && isNotValue is bool b)
@@ -2170,7 +2046,7 @@ namespace InABox.Core
                 result.IsNot = b;
             }
 
-            result.Expression = exp;
+            result.Property = prop;
             result.Operator = op;
             if(data.TryGetValue("Value", out var val))
             {
@@ -2180,7 +2056,7 @@ namespace InABox.Core
                     val = Activator.CreateInstance(typeof(SubQuery<>).MakeGenericType(CoreUtils.GetEntity(wrapper.Type)), null, null);
                     Serialization.DeserializeInto(wrapper.SerializedSubquery, val);
                 }
-                result.Value = CoreUtils.ChangeType(val, exp.Type);
+                result.Value = CoreUtils.ChangeType(val, result.Type);
             }
             else if(data.TryGetValue("FilterConstant", out var filterConstant))
             {

+ 1 - 1
InABox.Core/Serialization.cs

@@ -664,7 +664,7 @@ namespace InABox.Core
             var originalValues = new List<Tuple<Type, string, object?>>();
             foreach (var (key, value) in obj.OriginalValueList)
             {
-                if (DatabaseSchema.Property(obj.GetType(), key) is IProperty prop)
+                if (DatabaseSchema.Property(obj.GetType(), key) is IProperty prop && prop.IsSerializable)
                 {
                     originalValues.Add(new Tuple<Type, string, object?>(prop.PropertyType, key, value));
                 }

+ 7 - 19
inabox.database.sqlite/SQLiteProvider.cs

@@ -1825,7 +1825,7 @@ public class SQLiteProvider : IProvider
     private string GetFilterClauseNonGeneric(Type T, SQLiteCommand command, char prefix, IFilter? filter, List<Tuple<string, string, string, string>> tables,
         Dictionary<string, string> fieldmap, List<string> columns, bool useparams)
     {
-        if (filter == null || filter.Expression == null)
+        if (filter == null || filter.Property.IsNullOrWhiteSpace())
             return "";
 
         var result = "";
@@ -1839,18 +1839,7 @@ public class SQLiteProvider : IProvider
         }
         else
         {
-            string prop;
-            if (CoreUtils.TryFindMemberExpression(filter.Expression, out var mexp))
-            {
-                prop = CoreUtils.GetFullPropertyName(mexp, ".");
-            }
-            else
-            {
-                prop = filter.Expression.ToString();
-                if (prop.Contains("=>"))
-                    prop = string.Join(".", prop.Split('.').Skip(1));
-                mexp = CoreUtils.GetMemberExpression(T, prop);
-            }
+            var prop = filter.Property;
 
             LoadFieldsAndTables(command, T, prefix, fieldmap, tables, columns, Column.Create(T, prop), useparams);
             if (fieldmap.ContainsKey(prop))
@@ -1887,7 +1876,7 @@ public class SQLiteProvider : IProvider
                         foreach (var item in enumerable)
                         {
                             var sParam = string.Format("@p{0}", command.Parameters.Count);
-                            command.Parameters.AddWithValue(sParam, Encode(item, mexp.Type));
+                            command.Parameters.AddWithValue(sParam, Encode(item, filter.Type));
                             paramlist.Add(sParam);
                         }
 
@@ -1930,7 +1919,7 @@ public class SQLiteProvider : IProvider
                 }
                 else
                 {
-                    var value = Encode(filter.Value, mexp.Type);
+                    var value = Encode(filter.Value, filter.Type);
                     if (IsNull(value) && ((filter.Operator == Operator.IsEqualTo) || (filter.Operator == Operator.IsNotEqualTo)))
                     {
                         result = string.Format("({0} {1} NULL)", prop,
@@ -1944,7 +1933,7 @@ public class SQLiteProvider : IProvider
                         {
                             var sParam = string.Format("@p{0}", command.Parameters.Count);
 
-                            if (filter.Expression.Type == typeof(string[]))
+                            if (filter.Type == typeof(string[]))
                             {
                                 var bytes = Encoding.ASCII.GetBytes(value.ToString() ?? "");
                                 value = BitConverter.ToString(bytes).Replace("-", "");
@@ -2717,9 +2706,8 @@ public class SQLiteProvider : IProvider
             return;
         if (filter.Operator != Operator.None && filter.Operator != Operator.All)
         {
-            var exp = CoreUtils.GetFullPropertyName(CoreUtils.ExtractMemberExpression(filter.Expression), ".");
-            if (!fields.Contains(exp))
-                fields.Add(exp);
+            if (!fields.Contains(filter.Property))
+                fields.Add(filter.Property);
         }
         foreach (var and in filter.Ands)
             AddFilterFields(and, fields);

+ 1 - 1
inabox.wpf/DigitalForms/Designer/DynamicEditFormWindow.xaml.cs

@@ -342,7 +342,7 @@ public partial class DynamicFormEditWindow : Window, IDynamicFormWindow
                     {
                         var parentid = parentlink.ID;
                         var filter = Filter.Create(parenttype);
-                        filter.Expression = CoreUtils.GetMemberExpression(parenttype, "ID");
+                        filter.Property = "ID";
                         filter.Operator = Operator.IsEqualTo;
                         filter.Value = parentid;
 

+ 1 - 1
inabox.wpf/DynamicGrid/DynamicCrossJoinGrid.cs

@@ -38,7 +38,7 @@ public abstract class DynamicCrossJoinGrid<TEntity, TLeft> : DynamicDataGrid<TEn
         CancellationToken token, Action<CoreTable?, Exception?> action)
     {
         var filter = new Filter<TEntity>();
-        filter.Expression = CoreUtils.ExtractMemberExpression<TEntity, Guid>(LeftMapping);
+        filter.Property = CoreUtils.GetFullPropertyName(LeftMapping, ".");
         filter.Operator = Operator.IsEqualTo;
         filter.Value = CoreUtils.GetPropertyValue(Left, CoreUtils.GetFullPropertyName(LeftProperty, "."));
         criteria.Add(filter);

+ 2 - 2
inabox.wpf/DynamicGrid/DynamicDataGrid.cs

@@ -504,7 +504,7 @@ public class DynamicDataGrid<TEntity> : DynamicGrid<TEntity>, IDynamicDataGrid w
                 if (prop is not null)
                 {
                     var filter = Core.Filter.Create(childtype);
-                    filter.Expression = CoreUtils.GetMemberExpression(childtype, prop.Name + ".ID");
+                    filter.Property = prop.Name + ".ID";
                     filter.Operator = Operator.IsEqualTo;
                     filter.Value = id;
                     var sort = LookupFactory.DefineSort(childtype);
@@ -719,7 +719,7 @@ public class DynamicDataGrid<TEntity> : DynamicGrid<TEntity>, IDynamicDataGrid w
                 subQuery.Column = new Column<TEntity>(x => x.ID);
 
                 queryFilter = (Activator.CreateInstance(typeof(Filter<>).MakeGenericType(tableType)) as IFilter)!;
-                queryFilter.Expression = CoreUtils.GetMemberExpression(tableType, property.Name + ".ID");
+                queryFilter.Property = property.Name + ".ID";
                 queryFilter.InQuery(subQuery);
 
                 queries[tableType.Name] = new QueryDef(tableType)

+ 2 - 2
inabox.wpf/DynamicGrid/Editors/FilterEditor/FilterNode.cs

@@ -72,7 +72,7 @@ public class FilterNode<T> : BaseFilterNode
 
         this.filterType = filterType;
 
-        Property = new(filter.Expression) { Margin = new Thickness(0, 0, 5, 0) };
+        Property = new(filter.Property) { Margin = new Thickness(0, 0, 5, 0) };
         Operator = new(filter.Operator, filter.IsNot) { Margin = new Thickness(0, 0, 5, 0) };
 
         ValuePlaceHolder = CreateValuePlaceHolder();
@@ -159,7 +159,7 @@ public class FilterNode<T> : BaseFilterNode
             return null;
         
         var filter = new Filter<T>();
-        filter.Expression = CoreUtils.CreateMemberExpression(typeof(T), Property.SelectedProperty);
+        filter.Property = Property.SelectedProperty;
         filter.Operator = op;
         filter.IsNot = isNot;
         filter.Value = Constant?.SelectedConstant ?? CustomValue?.Value ?? Value.Value;

+ 2 - 3
inabox.wpf/DynamicGrid/Editors/FilterEditor/Nodes/PropertyNode.cs

@@ -27,7 +27,7 @@ public class PropertyNode<T> : Button
 
     private readonly string[] ColumnNames;
 
-    public PropertyNode(Expression expression)
+    public PropertyNode(string property)
     {
         VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
         VerticalContentAlignment = System.Windows.VerticalAlignment.Center;
@@ -52,8 +52,7 @@ public class PropertyNode<T> : Button
             .ToList();
         properties.Sort();
         ColumnNames = properties.ToArray();
-        if (CoreUtils.TryFindMemberExpression(expression, out var mexp))
-            SelectedProperty = CoreUtils.GetFullPropertyName(mexp, ".");
+        SelectedProperty = property;
 
         Click += PropertyNode_Click;
     }

+ 1 - 1
inabox.wpf/DynamicGrid/Editors/PopupEditor/PopupEditorControl.cs

@@ -155,7 +155,7 @@ public class PopupEditorControl : DynamicEditorControl<Guid, PopupEditor>
         var columns = LookupFactory.DefineLookupColumns(Host.GetEditorType(), _type, ColumnName);
         var sort = LookupFactory.DefineSort(_type);
         var filter = Filter.Create(_type);
-        filter.Expression = CoreUtils.GetMemberExpression(_type, "ID");
+        filter.Property = "ID";
         filter.Operator = Operator.IsEqualTo;
         filter.Value = value;
 

+ 1 - 3
inabox.wpf/DynamicGrid/MasterList.xaml.cs

@@ -172,12 +172,10 @@ namespace InABox.DynamicGrid
         {
             var filtertype = typeof(Filter<>).MakeGenericType(Type);
             var filter = Activator.CreateInstance(filtertype, "ID") as IFilter;
-            filter.Expression = CoreUtils.CreateMemberExpression(Type, "ID"); //CoreUtils.GetPropertyExpression(Type, "ID");
+            filter.Property = "ID";
             filter.Operator = Operator.InList;
             filter.Value = grid.SelectedRows.Select(r => r.Get<Guid>("ID")).ToArray();
             var model = Activator.CreateInstance(DataModelType, filter) as DataModel;
-            //MethodInfo print = typeof(ReportUtils).GetMethod("PrintMenu").MakeGenericMethod(Type);
-            //print.Invoke(null, new object[] { (FrameworkElement)sender, model, Security.CanEdit<Report>(), false });
         }
 
         private void Grid_OnCreateItem(object sender, object item)