This commit is contained in:
@@ -48,12 +48,14 @@ using System.Reflection;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using DynamORM.Builders;
|
using DynamORM.Builders;
|
||||||
using DynamORM.Builders.Extensions;
|
using DynamORM.Builders.Extensions;
|
||||||
using DynamORM.Builders.Implementation;
|
using DynamORM.Builders.Implementation;
|
||||||
using DynamORM.Helpers;
|
using DynamORM.Helpers;
|
||||||
using DynamORM.Helpers.Dynamics;
|
using DynamORM.Helpers.Dynamics;
|
||||||
using DynamORM.Mapper;
|
using DynamORM.Mapper;
|
||||||
|
using DynamORM.Validation;
|
||||||
|
|
||||||
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "This is a generated file which generates all the necessary support classes.")]
|
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "This is a generated file which generates all the necessary support classes.")]
|
||||||
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:FileMayOnlyContainASingleNamespace", Justification = "This is a generated file which generates all the necessary support classes.")]
|
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:FileMayOnlyContainASingleNamespace", Justification = "This is a generated file which generates all the necessary support classes.")]
|
||||||
@@ -2857,6 +2859,7 @@ namespace DynamORM
|
|||||||
{
|
{
|
||||||
case "varchar":
|
case "varchar":
|
||||||
return DbType.AnsiString;
|
return DbType.AnsiString;
|
||||||
|
|
||||||
case "nvarchar":
|
case "nvarchar":
|
||||||
return DbType.String;
|
return DbType.String;
|
||||||
}
|
}
|
||||||
@@ -5066,7 +5069,7 @@ namespace DynamORM
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Delegate fro try parse function of a type.</summary>
|
/// <summary>Delegate from try parse function of a type.</summary>
|
||||||
/// <typeparam name="T">Type which implements this function.</typeparam>
|
/// <typeparam name="T">Type which implements this function.</typeparam>
|
||||||
/// <param name="value">Value to parse.</param>
|
/// <param name="value">Value to parse.</param>
|
||||||
/// <param name="result">Resulting value.</param>
|
/// <param name="result">Resulting value.</param>
|
||||||
@@ -6510,7 +6513,7 @@ namespace DynamORM
|
|||||||
namespace Builders
|
namespace Builders
|
||||||
{
|
{
|
||||||
/// <summary>Dynamic delete query builder interface.</summary>
|
/// <summary>Dynamic delete query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicDeleteQueryBuilder : IDynamicQueryBuilder
|
public interface IDynamicDeleteQueryBuilder : IDynamicQueryBuilder
|
||||||
{
|
{
|
||||||
/// <summary>Execute this builder.</summary>
|
/// <summary>Execute this builder.</summary>
|
||||||
@@ -6556,7 +6559,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Dynamic insert query builder interface.</summary>
|
/// <summary>Dynamic insert query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicInsertQueryBuilder : IDynamicQueryBuilder
|
public interface IDynamicInsertQueryBuilder : IDynamicQueryBuilder
|
||||||
{
|
{
|
||||||
/// <summary>Execute this builder.</summary>
|
/// <summary>Execute this builder.</summary>
|
||||||
@@ -6587,7 +6590,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Dynamic query builder base interface.</summary>
|
/// <summary>Dynamic query builder base interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicQueryBuilder : IExtendedDisposable
|
public interface IDynamicQueryBuilder : IExtendedDisposable
|
||||||
{
|
{
|
||||||
/// <summary>Gets <see cref="DynamicDatabase"/> instance.</summary>
|
/// <summary>Gets <see cref="DynamicDatabase"/> instance.</summary>
|
||||||
@@ -6627,7 +6630,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Dynamic select query builder interface.</summary>
|
/// <summary>Dynamic select query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder ////, IEnumerable<object>
|
public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder ////, IEnumerable<object>
|
||||||
{
|
{
|
||||||
/// <summary>Execute this builder.</summary>
|
/// <summary>Execute this builder.</summary>
|
||||||
@@ -6881,7 +6884,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Dynamic update query builder interface.</summary>
|
/// <summary>Dynamic update query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicUpdateQueryBuilder : IDynamicQueryBuilder
|
public interface IDynamicUpdateQueryBuilder : IDynamicQueryBuilder
|
||||||
{
|
{
|
||||||
/// <summary>Execute this builder.</summary>
|
/// <summary>Execute this builder.</summary>
|
||||||
@@ -12420,8 +12423,16 @@ namespace DynamORM
|
|||||||
throw new ArgumentException(string.Format("Argument '{0}' must be dynamic.", p.Name));
|
throw new ArgumentException(string.Format("Argument '{0}' must be dynamic.", p.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
_uncertainResult = f.DynamicInvoke(_arguments.ToArray());
|
_uncertainResult = f.DynamicInvoke(_arguments.ToArray());
|
||||||
}
|
}
|
||||||
|
catch (TargetInvocationException e)
|
||||||
|
{
|
||||||
|
if (e.InnerException != null) throw e.InnerException;
|
||||||
|
else throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parses the dynamic lambda expression given in the form of a delegate, and returns a new instance of the
|
/// Parses the dynamic lambda expression given in the form of a delegate, and returns a new instance of the
|
||||||
@@ -13097,8 +13108,11 @@ namespace DynamORM
|
|||||||
public int Ordinal { get; set; }
|
public int Ordinal { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type _arrayType;
|
/// <summary>Gets the array type of property if main type is a form of collection.</summary>
|
||||||
private bool _genericEnumerable;
|
public Type ArrayType { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets a value indicating whether this property is in fact a generic list.</summary>
|
||||||
|
public bool IsGnericEnumerable { get; private set; }
|
||||||
|
|
||||||
/// <summary>Gets the type of property.</summary>
|
/// <summary>Gets the type of property.</summary>
|
||||||
public Type Type { get; private set; }
|
public Type Type { get; private set; }
|
||||||
@@ -13115,6 +13129,9 @@ namespace DynamORM
|
|||||||
/// <summary>Gets type column description.</summary>
|
/// <summary>Gets type column description.</summary>
|
||||||
public ColumnAttribute Column { get; private set; }
|
public ColumnAttribute Column { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets type list of property requirements.</summary>
|
||||||
|
public List<RequiredAttribute> Requirements { get; private set; }
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether this <see cref="DynamicPropertyInvoker"/> is ignored in some cases.</summary>
|
/// <summary>Gets a value indicating whether this <see cref="DynamicPropertyInvoker"/> is ignored in some cases.</summary>
|
||||||
public bool Ignore { get; private set; }
|
public bool Ignore { get; private set; }
|
||||||
|
|
||||||
@@ -13130,21 +13147,22 @@ namespace DynamORM
|
|||||||
Type = property.PropertyType;
|
Type = property.PropertyType;
|
||||||
|
|
||||||
object[] ignore = property.GetCustomAttributes(typeof(IgnoreAttribute), false);
|
object[] ignore = property.GetCustomAttributes(typeof(IgnoreAttribute), false);
|
||||||
|
Requirements = property.GetCustomAttributes(typeof(RequiredAttribute), false).Cast<RequiredAttribute>().ToList();
|
||||||
|
|
||||||
Ignore = ignore != null && ignore.Length > 0;
|
Ignore = ignore != null && ignore.Length > 0;
|
||||||
|
|
||||||
_arrayType = Type.IsArray ? Type.GetElementType() :
|
IsGnericEnumerable = Type.IsGenericEnumerable();
|
||||||
Type.IsGenericEnumerable() ? Type.GetGenericArguments().First() :
|
|
||||||
|
ArrayType = Type.IsArray ? Type.GetElementType() :
|
||||||
|
IsGnericEnumerable ? Type.GetGenericArguments().First() :
|
||||||
Type;
|
Type;
|
||||||
|
|
||||||
_genericEnumerable = Type.IsGenericEnumerable();
|
IsDataContract = ArrayType.GetCustomAttributes(false).Any(x => x.GetType().Name == "DataContractAttribute");
|
||||||
|
|
||||||
IsDataContract = _arrayType.GetCustomAttributes(false).Any(x => x.GetType().Name == "DataContractAttribute");
|
if (ArrayType.IsArray)
|
||||||
|
|
||||||
if (_arrayType.IsArray)
|
|
||||||
throw new InvalidOperationException("Jagged arrays are not supported");
|
throw new InvalidOperationException("Jagged arrays are not supported");
|
||||||
|
|
||||||
if (_arrayType.IsGenericEnumerable())
|
if (ArrayType.IsGenericEnumerable())
|
||||||
throw new InvalidOperationException("Enumerables of enumerables are not supported");
|
throw new InvalidOperationException("Enumerables of enumerables are not supported");
|
||||||
|
|
||||||
Column = attr;
|
Column = attr;
|
||||||
@@ -13199,20 +13217,20 @@ namespace DynamORM
|
|||||||
{
|
{
|
||||||
if (!Type.IsAssignableFrom(val.GetType()))
|
if (!Type.IsAssignableFrom(val.GetType()))
|
||||||
{
|
{
|
||||||
if (Type.IsArray || _genericEnumerable)
|
if (Type.IsArray || IsGnericEnumerable)
|
||||||
{
|
{
|
||||||
if (val != null)
|
if (val != null)
|
||||||
{
|
{
|
||||||
var lst = (val as IEnumerable<object>).Select(x => GetElementVal(_arrayType, x)).ToList();
|
var lst = (val as IEnumerable<object>).Select(x => GetElementVal(ArrayType, x)).ToList();
|
||||||
|
|
||||||
value = Array.CreateInstance(_arrayType, lst.Count);
|
value = Array.CreateInstance(ArrayType, lst.Count);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var e in lst)
|
foreach (var e in lst)
|
||||||
((Array)value).SetValue(e, i++);
|
((Array)value).SetValue(e, i++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
value = Array.CreateInstance(_arrayType, 0);
|
value = Array.CreateInstance(ArrayType, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
value = GetElementVal(Type, val);
|
value = GetElementVal(Type, val);
|
||||||
@@ -13248,7 +13266,17 @@ namespace DynamORM
|
|||||||
else if (type.IsEnum && val.GetType().IsValueType)
|
else if (type.IsEnum && val.GetType().IsValueType)
|
||||||
return Enum.ToObject(type, val);
|
return Enum.ToObject(type, val);
|
||||||
else if (type.IsEnum)
|
else if (type.IsEnum)
|
||||||
|
try
|
||||||
|
{
|
||||||
return Enum.Parse(type, val.ToString());
|
return Enum.Parse(type, val.ToString());
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
if (nullable)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
else if (Type == typeof(string) && val.GetType() == typeof(Guid))
|
else if (Type == typeof(string) && val.GetType() == typeof(Guid))
|
||||||
return val.ToString();
|
return val.ToString();
|
||||||
else if (Type == typeof(Guid) && val.GetType() == typeof(string))
|
else if (Type == typeof(Guid) && val.GetType() == typeof(string))
|
||||||
@@ -13259,8 +13287,18 @@ namespace DynamORM
|
|||||||
else if (IsDataContract)
|
else if (IsDataContract)
|
||||||
return val.Map(type);
|
return val.Map(type);
|
||||||
else
|
else
|
||||||
|
try
|
||||||
|
{
|
||||||
return Convert.ChangeType(val, type);
|
return Convert.ChangeType(val, type);
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (nullable)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Type command cache
|
#region Type command cache
|
||||||
|
|
||||||
@@ -13377,6 +13415,57 @@ namespace DynamORM
|
|||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Validates the object.</summary>
|
||||||
|
/// <param name="val">The value.</param>
|
||||||
|
/// <returns>List of not valid results.</returns>
|
||||||
|
public IList<ValidationResult> ValidateObject(object val)
|
||||||
|
{
|
||||||
|
var result = new List<ValidationResult>();
|
||||||
|
|
||||||
|
if (val == null || val.GetType() != Type)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
foreach (var prop in ColumnsMap.Values)
|
||||||
|
{
|
||||||
|
if (prop.Requirements == null || !prop.Requirements.Any())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var v = prop.Get(val);
|
||||||
|
|
||||||
|
foreach (var r in prop.Requirements)
|
||||||
|
{
|
||||||
|
var valid = r.ValidateSimpleValue(prop, v);
|
||||||
|
|
||||||
|
if (valid == ValidateResult.Valid)
|
||||||
|
{
|
||||||
|
if (prop.Type.IsArray || prop.IsGnericEnumerable)
|
||||||
|
{
|
||||||
|
var map = DynamicMapperCache.GetMapper(prop.ArrayType);
|
||||||
|
foreach (var item in val as IEnumerable<object>)
|
||||||
|
result.AddRange(map.ValidateObject(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid == ValidateResult.NotSupported)
|
||||||
|
{
|
||||||
|
result.AddRange(DynamicMapperCache.GetMapper(prop.Type).ValidateObject(v));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(new ValidationResult()
|
||||||
|
{
|
||||||
|
Property = prop,
|
||||||
|
Requirement = r,
|
||||||
|
Value = v,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable<MemberInfo> GetAllMembers(Type type)
|
private IEnumerable<MemberInfo> GetAllMembers(Type type)
|
||||||
{
|
{
|
||||||
if (type.IsInterface)
|
if (type.IsInterface)
|
||||||
@@ -13451,4 +13540,167 @@ namespace DynamORM
|
|||||||
public bool Override { get; set; }
|
public bool Override { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Validation
|
||||||
|
{
|
||||||
|
/// <summary>Required attribute can be used to validate fields in objects using mapper class.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public class RequiredAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>Gets or sets minimum value or length of field.</summary>
|
||||||
|
public decimal? Min { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Gets or sets maximum value or length of field.</summary>
|
||||||
|
public decimal? Max { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Gets or sets pattern to verify.</summary>
|
||||||
|
public Regex Pattern { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Gets or sets a value indicating whether property value is required or not.</summary>
|
||||||
|
public bool Required { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Initializes a new instance of the <see cref="RequiredAttribute" /> class.</summary>
|
||||||
|
/// <param name="required">This field will be required.</param>
|
||||||
|
public RequiredAttribute(bool required = true)
|
||||||
|
{
|
||||||
|
Required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Initializes a new instance of the <see cref="RequiredAttribute" /> class.</summary>
|
||||||
|
/// <param name="val">Limiting value to set.</param>
|
||||||
|
/// <param name="max">Whether set maximum parameter (true) or minimum parameter (false).</param>
|
||||||
|
/// <param name="required">This field will be required.</param>
|
||||||
|
public RequiredAttribute(float val, bool max, bool required = true)
|
||||||
|
{
|
||||||
|
if (max)
|
||||||
|
Max = (decimal)val;
|
||||||
|
else
|
||||||
|
Min = (decimal)val;
|
||||||
|
Required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Initializes a new instance of the <see cref="RequiredAttribute" /> class.</summary>
|
||||||
|
/// <param name="min">Minimum value to set.</param>
|
||||||
|
/// <param name="max">Maximum value to set.</param>
|
||||||
|
/// <param name="required">This field will be required.</param>
|
||||||
|
public RequiredAttribute(float min, float max, bool required = true)
|
||||||
|
{
|
||||||
|
Min = (decimal)min;
|
||||||
|
Max = (decimal)max;
|
||||||
|
Required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Initializes a new instance of the <see cref="RequiredAttribute" /> class.</summary>
|
||||||
|
/// <param name="min">Minimum value to set.</param>
|
||||||
|
/// <param name="max">Maximum value to set.</param>
|
||||||
|
/// <param name="pattern">Pattern to check.</param>
|
||||||
|
/// <param name="required">This field will be required.</param>
|
||||||
|
public RequiredAttribute(float min, float max, string pattern, bool required = true)
|
||||||
|
{
|
||||||
|
Min = (decimal)min;
|
||||||
|
Max = (decimal)max;
|
||||||
|
Pattern = new Regex(pattern, RegexOptions.Compiled);
|
||||||
|
Required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal ValidateResult ValidateSimpleValue(DynamicPropertyInvoker dpi, object val)
|
||||||
|
{
|
||||||
|
if (val == null && Required)
|
||||||
|
return ValidateResult.ValueIsMissing;
|
||||||
|
|
||||||
|
if (dpi.Type.IsValueType)
|
||||||
|
{
|
||||||
|
if (val is decimal || val is long || val is int || val is float || val is double || val is short || val is byte ||
|
||||||
|
val is decimal? || val is long? || val is int? || val is float? || val is double? || val is short? || val is byte?)
|
||||||
|
{
|
||||||
|
decimal dec = Convert.ToDecimal(val);
|
||||||
|
|
||||||
|
if (Min.HasValue && Min.Value > dec)
|
||||||
|
return ValidateResult.ValueTooSmall;
|
||||||
|
|
||||||
|
if (Max.HasValue && Max.Value < dec)
|
||||||
|
return ValidateResult.ValueTooLarge;
|
||||||
|
|
||||||
|
return ValidateResult.Valid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var str = val.ToString();
|
||||||
|
|
||||||
|
if (Min.HasValue && Min.Value > str.Length)
|
||||||
|
return ValidateResult.ValueTooShort;
|
||||||
|
|
||||||
|
if (Max.HasValue && Max.Value < str.Length)
|
||||||
|
return ValidateResult.ValueTooLong;
|
||||||
|
|
||||||
|
if (Pattern != null && !Pattern.IsMatch(str))
|
||||||
|
return ValidateResult.ValueDontMatchPattern;
|
||||||
|
|
||||||
|
return ValidateResult.Valid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dpi.Type.IsArray || dpi.IsGnericEnumerable)
|
||||||
|
{
|
||||||
|
var cnt = (val as IEnumerable<object>).Count();
|
||||||
|
|
||||||
|
if (Min.HasValue && Min.Value > cnt)
|
||||||
|
return ValidateResult.TooFewElementsInCollection;
|
||||||
|
|
||||||
|
if (Max.HasValue && Max.Value < cnt)
|
||||||
|
return ValidateResult.TooManyElementsInCollection;
|
||||||
|
|
||||||
|
return ValidateResult.Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidateResult.NotSupported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Validation result enum.</summary>
|
||||||
|
public enum ValidateResult
|
||||||
|
{
|
||||||
|
/// <summary>The valid value.</summary>
|
||||||
|
Valid,
|
||||||
|
|
||||||
|
/// <summary>The value is missing.</summary>
|
||||||
|
ValueIsMissing,
|
||||||
|
|
||||||
|
/// <summary>The value too small.</summary>
|
||||||
|
ValueTooSmall,
|
||||||
|
|
||||||
|
/// <summary>The value too large.</summary>
|
||||||
|
ValueTooLarge,
|
||||||
|
|
||||||
|
/// <summary>The too few elements in collection.</summary>
|
||||||
|
TooFewElementsInCollection,
|
||||||
|
|
||||||
|
/// <summary>The too many elements in collection.</summary>
|
||||||
|
TooManyElementsInCollection,
|
||||||
|
|
||||||
|
/// <summary>The value too short.</summary>
|
||||||
|
ValueTooShort,
|
||||||
|
|
||||||
|
/// <summary>The value too long.</summary>
|
||||||
|
ValueTooLong,
|
||||||
|
|
||||||
|
/// <summary>The value don't match pattern.</summary>
|
||||||
|
ValueDontMatchPattern,
|
||||||
|
|
||||||
|
/// <summary>The not supported.</summary>
|
||||||
|
NotSupported,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Validation result.</summary>
|
||||||
|
public class ValidationResult
|
||||||
|
{
|
||||||
|
/// <summary>Gets the property invoker.</summary>
|
||||||
|
public DynamicPropertyInvoker Property { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>Gets the requirement definition.</summary>
|
||||||
|
public RequiredAttribute Requirement { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>Gets the value that is broken.</summary>
|
||||||
|
public object Value { get; internal set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ using System;
|
|||||||
namespace DynamORM.Builders
|
namespace DynamORM.Builders
|
||||||
{
|
{
|
||||||
/// <summary>Dynamic delete query builder interface.</summary>
|
/// <summary>Dynamic delete query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicDeleteQueryBuilder : IDynamicQueryBuilder
|
public interface IDynamicDeleteQueryBuilder : IDynamicQueryBuilder
|
||||||
{
|
{
|
||||||
/// <summary>Execute this builder.</summary>
|
/// <summary>Execute this builder.</summary>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ using System;
|
|||||||
namespace DynamORM.Builders
|
namespace DynamORM.Builders
|
||||||
{
|
{
|
||||||
/// <summary>Dynamic insert query builder interface.</summary>
|
/// <summary>Dynamic insert query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicInsertQueryBuilder : IDynamicQueryBuilder
|
public interface IDynamicInsertQueryBuilder : IDynamicQueryBuilder
|
||||||
{
|
{
|
||||||
/// <summary>Execute this builder.</summary>
|
/// <summary>Execute this builder.</summary>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ using DynamORM.Helpers;
|
|||||||
namespace DynamORM.Builders
|
namespace DynamORM.Builders
|
||||||
{
|
{
|
||||||
/// <summary>Dynamic query builder base interface.</summary>
|
/// <summary>Dynamic query builder base interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicQueryBuilder : IExtendedDisposable
|
public interface IDynamicQueryBuilder : IExtendedDisposable
|
||||||
{
|
{
|
||||||
/// <summary>Gets <see cref="DynamicDatabase"/> instance.</summary>
|
/// <summary>Gets <see cref="DynamicDatabase"/> instance.</summary>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ using System.Data;
|
|||||||
namespace DynamORM.Builders
|
namespace DynamORM.Builders
|
||||||
{
|
{
|
||||||
/// <summary>Dynamic select query builder interface.</summary>
|
/// <summary>Dynamic select query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder ////, IEnumerable<object>
|
public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder ////, IEnumerable<object>
|
||||||
{
|
{
|
||||||
/// <summary>Execute this builder.</summary>
|
/// <summary>Execute this builder.</summary>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ using System;
|
|||||||
namespace DynamORM.Builders
|
namespace DynamORM.Builders
|
||||||
{
|
{
|
||||||
/// <summary>Dynamic update query builder interface.</summary>
|
/// <summary>Dynamic update query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publicly available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicUpdateQueryBuilder : IDynamicQueryBuilder
|
public interface IDynamicUpdateQueryBuilder : IDynamicQueryBuilder
|
||||||
{
|
{
|
||||||
/// <summary>Execute this builder.</summary>
|
/// <summary>Execute this builder.</summary>
|
||||||
|
|||||||
@@ -104,11 +104,14 @@
|
|||||||
<Compile Include="Mapper\DynamicPropertyInvoker.cs" />
|
<Compile Include="Mapper\DynamicPropertyInvoker.cs" />
|
||||||
<Compile Include="Mapper\DynamicTypeMap.cs" />
|
<Compile Include="Mapper\DynamicTypeMap.cs" />
|
||||||
<Compile Include="Mapper\IgnoreAttribute.cs" />
|
<Compile Include="Mapper\IgnoreAttribute.cs" />
|
||||||
|
<Compile Include="Validation\RequiredAttribute.cs" />
|
||||||
<Compile Include="Mapper\TableAttribute.cs" />
|
<Compile Include="Mapper\TableAttribute.cs" />
|
||||||
<Compile Include="Mapper\DynamicCast.cs" />
|
<Compile Include="Mapper\DynamicCast.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="DynamicExpando.cs" />
|
<Compile Include="DynamicExpando.cs" />
|
||||||
<Compile Include="Helpers\IFinalizerDisposable.cs" />
|
<Compile Include="Helpers\IFinalizerDisposable.cs" />
|
||||||
|
<Compile Include="Validation\ValidateResult.cs" />
|
||||||
|
<Compile Include="Validation\ValidationResult.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|||||||
@@ -1398,6 +1398,7 @@ namespace DynamORM
|
|||||||
{
|
{
|
||||||
case "varchar":
|
case "varchar":
|
||||||
return DbType.AnsiString;
|
return DbType.AnsiString;
|
||||||
|
|
||||||
case "nvarchar":
|
case "nvarchar":
|
||||||
return DbType.String;
|
return DbType.String;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1605,7 +1605,7 @@ namespace DynamORM
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Delegate fro try parse function of a type.</summary>
|
/// <summary>Delegate from try parse function of a type.</summary>
|
||||||
/// <typeparam name="T">Type which implements this function.</typeparam>
|
/// <typeparam name="T">Type which implements this function.</typeparam>
|
||||||
/// <param name="value">Value to parse.</param>
|
/// <param name="value">Value to parse.</param>
|
||||||
/// <param name="result">Resulting value.</param>
|
/// <param name="result">Resulting value.</param>
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|||||||
@@ -438,7 +438,6 @@ namespace DynamORM.Helpers.Dynamics
|
|||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
@@ -650,7 +649,6 @@ namespace DynamORM.Helpers.Dynamics
|
|||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
@@ -839,7 +837,6 @@ namespace DynamORM.Helpers.Dynamics
|
|||||||
return string.Format("{0}.{1}{2}", Host.Sketch(), Name.Sketch(), Arguments == null ? "()" : Arguments.Sketch(brackets: "()".ToCharArray()));
|
return string.Format("{0}.{1}{2}", Host.Sketch(), Name.Sketch(), Arguments == null ? "()" : Arguments.Sketch(brackets: "()".ToCharArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Performs application-defined tasks associated with
|
/// <summary>Performs application-defined tasks associated with
|
||||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||||
/// <param name="disposing">If set to <c>true</c> dispose object.</param>
|
/// <param name="disposing">If set to <c>true</c> dispose object.</param>
|
||||||
@@ -875,7 +872,6 @@ namespace DynamORM.Helpers.Dynamics
|
|||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Method
|
#endregion Method
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ using System.Data;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using DynamORM.Validation;
|
||||||
|
|
||||||
namespace DynamORM.Mapper
|
namespace DynamORM.Mapper
|
||||||
{
|
{
|
||||||
@@ -47,8 +48,11 @@ namespace DynamORM.Mapper
|
|||||||
public int Ordinal { get; set; }
|
public int Ordinal { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type _arrayType;
|
/// <summary>Gets the array type of property if main type is a form of collection.</summary>
|
||||||
private bool _genericEnumerable;
|
public Type ArrayType { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets a value indicating whether this property is in fact a generic list.</summary>
|
||||||
|
public bool IsGnericEnumerable { get; private set; }
|
||||||
|
|
||||||
/// <summary>Gets the type of property.</summary>
|
/// <summary>Gets the type of property.</summary>
|
||||||
public Type Type { get; private set; }
|
public Type Type { get; private set; }
|
||||||
@@ -65,6 +69,9 @@ namespace DynamORM.Mapper
|
|||||||
/// <summary>Gets type column description.</summary>
|
/// <summary>Gets type column description.</summary>
|
||||||
public ColumnAttribute Column { get; private set; }
|
public ColumnAttribute Column { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets type list of property requirements.</summary>
|
||||||
|
public List<RequiredAttribute> Requirements { get; private set; }
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether this <see cref="DynamicPropertyInvoker"/> is ignored in some cases.</summary>
|
/// <summary>Gets a value indicating whether this <see cref="DynamicPropertyInvoker"/> is ignored in some cases.</summary>
|
||||||
public bool Ignore { get; private set; }
|
public bool Ignore { get; private set; }
|
||||||
|
|
||||||
@@ -80,21 +87,22 @@ namespace DynamORM.Mapper
|
|||||||
Type = property.PropertyType;
|
Type = property.PropertyType;
|
||||||
|
|
||||||
object[] ignore = property.GetCustomAttributes(typeof(IgnoreAttribute), false);
|
object[] ignore = property.GetCustomAttributes(typeof(IgnoreAttribute), false);
|
||||||
|
Requirements = property.GetCustomAttributes(typeof(RequiredAttribute), false).Cast<RequiredAttribute>().ToList();
|
||||||
|
|
||||||
Ignore = ignore != null && ignore.Length > 0;
|
Ignore = ignore != null && ignore.Length > 0;
|
||||||
|
|
||||||
_arrayType = Type.IsArray ? Type.GetElementType() :
|
IsGnericEnumerable = Type.IsGenericEnumerable();
|
||||||
Type.IsGenericEnumerable() ? Type.GetGenericArguments().First() :
|
|
||||||
|
ArrayType = Type.IsArray ? Type.GetElementType() :
|
||||||
|
IsGnericEnumerable ? Type.GetGenericArguments().First() :
|
||||||
Type;
|
Type;
|
||||||
|
|
||||||
_genericEnumerable = Type.IsGenericEnumerable();
|
IsDataContract = ArrayType.GetCustomAttributes(false).Any(x => x.GetType().Name == "DataContractAttribute");
|
||||||
|
|
||||||
IsDataContract = _arrayType.GetCustomAttributes(false).Any(x => x.GetType().Name == "DataContractAttribute");
|
if (ArrayType.IsArray)
|
||||||
|
|
||||||
if (_arrayType.IsArray)
|
|
||||||
throw new InvalidOperationException("Jagged arrays are not supported");
|
throw new InvalidOperationException("Jagged arrays are not supported");
|
||||||
|
|
||||||
if (_arrayType.IsGenericEnumerable())
|
if (ArrayType.IsGenericEnumerable())
|
||||||
throw new InvalidOperationException("Enumerables of enumerables are not supported");
|
throw new InvalidOperationException("Enumerables of enumerables are not supported");
|
||||||
|
|
||||||
Column = attr;
|
Column = attr;
|
||||||
@@ -149,20 +157,20 @@ namespace DynamORM.Mapper
|
|||||||
{
|
{
|
||||||
if (!Type.IsAssignableFrom(val.GetType()))
|
if (!Type.IsAssignableFrom(val.GetType()))
|
||||||
{
|
{
|
||||||
if (Type.IsArray || _genericEnumerable)
|
if (Type.IsArray || IsGnericEnumerable)
|
||||||
{
|
{
|
||||||
if (val != null)
|
if (val != null)
|
||||||
{
|
{
|
||||||
var lst = (val as IEnumerable<object>).Select(x => GetElementVal(_arrayType, x)).ToList();
|
var lst = (val as IEnumerable<object>).Select(x => GetElementVal(ArrayType, x)).ToList();
|
||||||
|
|
||||||
value = Array.CreateInstance(_arrayType, lst.Count);
|
value = Array.CreateInstance(ArrayType, lst.Count);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var e in lst)
|
foreach (var e in lst)
|
||||||
((Array)value).SetValue(e, i++);
|
((Array)value).SetValue(e, i++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
value = Array.CreateInstance(_arrayType, 0);
|
value = Array.CreateInstance(ArrayType, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
value = GetElementVal(Type, val);
|
value = GetElementVal(Type, val);
|
||||||
@@ -198,7 +206,17 @@ namespace DynamORM.Mapper
|
|||||||
else if (type.IsEnum && val.GetType().IsValueType)
|
else if (type.IsEnum && val.GetType().IsValueType)
|
||||||
return Enum.ToObject(type, val);
|
return Enum.ToObject(type, val);
|
||||||
else if (type.IsEnum)
|
else if (type.IsEnum)
|
||||||
|
try
|
||||||
|
{
|
||||||
return Enum.Parse(type, val.ToString());
|
return Enum.Parse(type, val.ToString());
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
if (nullable)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
else if (Type == typeof(string) && val.GetType() == typeof(Guid))
|
else if (Type == typeof(string) && val.GetType() == typeof(Guid))
|
||||||
return val.ToString();
|
return val.ToString();
|
||||||
else if (Type == typeof(Guid) && val.GetType() == typeof(string))
|
else if (Type == typeof(Guid) && val.GetType() == typeof(string))
|
||||||
@@ -209,8 +227,18 @@ namespace DynamORM.Mapper
|
|||||||
else if (IsDataContract)
|
else if (IsDataContract)
|
||||||
return val.Map(type);
|
return val.Map(type);
|
||||||
else
|
else
|
||||||
|
try
|
||||||
|
{
|
||||||
return Convert.ChangeType(val, type);
|
return Convert.ChangeType(val, type);
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (nullable)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Type command cache
|
#region Type command cache
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using DynamORM.Validation;
|
||||||
|
|
||||||
namespace DynamORM.Mapper
|
namespace DynamORM.Mapper
|
||||||
{
|
{
|
||||||
@@ -138,6 +139,57 @@ namespace DynamORM.Mapper
|
|||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Validates the object.</summary>
|
||||||
|
/// <param name="val">The value.</param>
|
||||||
|
/// <returns>List of not valid results.</returns>
|
||||||
|
public IList<ValidationResult> ValidateObject(object val)
|
||||||
|
{
|
||||||
|
var result = new List<ValidationResult>();
|
||||||
|
|
||||||
|
if (val == null || val.GetType() != Type)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
foreach (var prop in ColumnsMap.Values)
|
||||||
|
{
|
||||||
|
if (prop.Requirements == null || !prop.Requirements.Any())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var v = prop.Get(val);
|
||||||
|
|
||||||
|
foreach (var r in prop.Requirements)
|
||||||
|
{
|
||||||
|
var valid = r.ValidateSimpleValue(prop, v);
|
||||||
|
|
||||||
|
if (valid == ValidateResult.Valid)
|
||||||
|
{
|
||||||
|
if (prop.Type.IsArray || prop.IsGnericEnumerable)
|
||||||
|
{
|
||||||
|
var map = DynamicMapperCache.GetMapper(prop.ArrayType);
|
||||||
|
foreach (var item in val as IEnumerable<object>)
|
||||||
|
result.AddRange(map.ValidateObject(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid == ValidateResult.NotSupported)
|
||||||
|
{
|
||||||
|
result.AddRange(DynamicMapperCache.GetMapper(prop.Type).ValidateObject(v));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(new ValidationResult()
|
||||||
|
{
|
||||||
|
Property = prop,
|
||||||
|
Requirement = r,
|
||||||
|
Value = v,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable<MemberInfo> GetAllMembers(Type type)
|
private IEnumerable<MemberInfo> GetAllMembers(Type type)
|
||||||
{
|
{
|
||||||
if (type.IsInterface)
|
if (type.IsInterface)
|
||||||
|
|||||||
121
DynamORM/Validation/RequiredAttribute.cs
Normal file
121
DynamORM/Validation/RequiredAttribute.cs
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using DynamORM.Mapper;
|
||||||
|
|
||||||
|
namespace DynamORM.Validation
|
||||||
|
{
|
||||||
|
/// <summary>Required attribute can be used to validate fields in objects using mapper class.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public class RequiredAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>Gets or sets minimum value or length of field.</summary>
|
||||||
|
public decimal? Min { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Gets or sets maximum value or length of field.</summary>
|
||||||
|
public decimal? Max { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Gets or sets pattern to verify.</summary>
|
||||||
|
public Regex Pattern { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Gets or sets a value indicating whether property value is required or not.</summary>
|
||||||
|
public bool Required { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Initializes a new instance of the <see cref="RequiredAttribute" /> class.</summary>
|
||||||
|
/// <param name="required">This field will be required.</param>
|
||||||
|
public RequiredAttribute(bool required = true)
|
||||||
|
{
|
||||||
|
Required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Initializes a new instance of the <see cref="RequiredAttribute" /> class.</summary>
|
||||||
|
/// <param name="val">Limiting value to set.</param>
|
||||||
|
/// <param name="max">Whether set maximum parameter (true) or minimum parameter (false).</param>
|
||||||
|
/// <param name="required">This field will be required.</param>
|
||||||
|
public RequiredAttribute(float val, bool max, bool required = true)
|
||||||
|
{
|
||||||
|
if (max)
|
||||||
|
Max = (decimal)val;
|
||||||
|
else
|
||||||
|
Min = (decimal)val;
|
||||||
|
Required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Initializes a new instance of the <see cref="RequiredAttribute" /> class.</summary>
|
||||||
|
/// <param name="min">Minimum value to set.</param>
|
||||||
|
/// <param name="max">Maximum value to set.</param>
|
||||||
|
/// <param name="required">This field will be required.</param>
|
||||||
|
public RequiredAttribute(float min, float max, bool required = true)
|
||||||
|
{
|
||||||
|
Min = (decimal)min;
|
||||||
|
Max = (decimal)max;
|
||||||
|
Required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Initializes a new instance of the <see cref="RequiredAttribute" /> class.</summary>
|
||||||
|
/// <param name="min">Minimum value to set.</param>
|
||||||
|
/// <param name="max">Maximum value to set.</param>
|
||||||
|
/// <param name="pattern">Pattern to check.</param>
|
||||||
|
/// <param name="required">This field will be required.</param>
|
||||||
|
public RequiredAttribute(float min, float max, string pattern, bool required = true)
|
||||||
|
{
|
||||||
|
Min = (decimal)min;
|
||||||
|
Max = (decimal)max;
|
||||||
|
Pattern = new Regex(pattern, RegexOptions.Compiled);
|
||||||
|
Required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal ValidateResult ValidateSimpleValue(DynamicPropertyInvoker dpi, object val)
|
||||||
|
{
|
||||||
|
if (val == null && Required)
|
||||||
|
return ValidateResult.ValueIsMissing;
|
||||||
|
|
||||||
|
if (dpi.Type.IsValueType)
|
||||||
|
{
|
||||||
|
if (val is decimal || val is long || val is int || val is float || val is double || val is short || val is byte ||
|
||||||
|
val is decimal? || val is long? || val is int? || val is float? || val is double? || val is short? || val is byte?)
|
||||||
|
{
|
||||||
|
decimal dec = Convert.ToDecimal(val);
|
||||||
|
|
||||||
|
if (Min.HasValue && Min.Value > dec)
|
||||||
|
return ValidateResult.ValueTooSmall;
|
||||||
|
|
||||||
|
if (Max.HasValue && Max.Value < dec)
|
||||||
|
return ValidateResult.ValueTooLarge;
|
||||||
|
|
||||||
|
return ValidateResult.Valid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var str = val.ToString();
|
||||||
|
|
||||||
|
if (Min.HasValue && Min.Value > str.Length)
|
||||||
|
return ValidateResult.ValueTooShort;
|
||||||
|
|
||||||
|
if (Max.HasValue && Max.Value < str.Length)
|
||||||
|
return ValidateResult.ValueTooLong;
|
||||||
|
|
||||||
|
if (Pattern != null && !Pattern.IsMatch(str))
|
||||||
|
return ValidateResult.ValueDontMatchPattern;
|
||||||
|
|
||||||
|
return ValidateResult.Valid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dpi.Type.IsArray || dpi.IsGnericEnumerable)
|
||||||
|
{
|
||||||
|
var cnt = (val as IEnumerable<object>).Count();
|
||||||
|
|
||||||
|
if (Min.HasValue && Min.Value > cnt)
|
||||||
|
return ValidateResult.TooFewElementsInCollection;
|
||||||
|
|
||||||
|
if (Max.HasValue && Max.Value < cnt)
|
||||||
|
return ValidateResult.TooManyElementsInCollection;
|
||||||
|
|
||||||
|
return ValidateResult.Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidateResult.NotSupported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
DynamORM/Validation/ValidateResult.cs
Normal file
36
DynamORM/Validation/ValidateResult.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
namespace DynamORM.Validation
|
||||||
|
{
|
||||||
|
/// <summary>Validation result enum.</summary>
|
||||||
|
public enum ValidateResult
|
||||||
|
{
|
||||||
|
/// <summary>The valid value.</summary>
|
||||||
|
Valid,
|
||||||
|
|
||||||
|
/// <summary>The value is missing.</summary>
|
||||||
|
ValueIsMissing,
|
||||||
|
|
||||||
|
/// <summary>The value too small.</summary>
|
||||||
|
ValueTooSmall,
|
||||||
|
|
||||||
|
/// <summary>The value too large.</summary>
|
||||||
|
ValueTooLarge,
|
||||||
|
|
||||||
|
/// <summary>The too few elements in collection.</summary>
|
||||||
|
TooFewElementsInCollection,
|
||||||
|
|
||||||
|
/// <summary>The too many elements in collection.</summary>
|
||||||
|
TooManyElementsInCollection,
|
||||||
|
|
||||||
|
/// <summary>The value too short.</summary>
|
||||||
|
ValueTooShort,
|
||||||
|
|
||||||
|
/// <summary>The value too long.</summary>
|
||||||
|
ValueTooLong,
|
||||||
|
|
||||||
|
/// <summary>The value don't match pattern.</summary>
|
||||||
|
ValueDontMatchPattern,
|
||||||
|
|
||||||
|
/// <summary>The not supported.</summary>
|
||||||
|
NotSupported,
|
||||||
|
}
|
||||||
|
}
|
||||||
17
DynamORM/Validation/ValidationResult.cs
Normal file
17
DynamORM/Validation/ValidationResult.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using DynamORM.Mapper;
|
||||||
|
|
||||||
|
namespace DynamORM.Validation
|
||||||
|
{
|
||||||
|
/// <summary>Validation result.</summary>
|
||||||
|
public class ValidationResult
|
||||||
|
{
|
||||||
|
/// <summary>Gets the property invoker.</summary>
|
||||||
|
public DynamicPropertyInvoker Property { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>Gets the requirement definition.</summary>
|
||||||
|
public RequiredAttribute Requirement { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>Gets the value that is broken.</summary>
|
||||||
|
public object Value { get; internal set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
234
Settings.StyleCop
Normal file
234
Settings.StyleCop
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
<StyleCopSettings Version="105">
|
||||||
|
<GlobalSettings>
|
||||||
|
<StringProperty Name="MergeSettingsFiles">NoMerge</StringProperty>
|
||||||
|
<CollectionProperty Name="RecognizedWords">
|
||||||
|
<Value>aspx</Value>
|
||||||
|
<Value>behaviour</Value>
|
||||||
|
<Value>bindable</Value>
|
||||||
|
<Value>cloneable</Value>
|
||||||
|
<Value>Cron</Value>
|
||||||
|
<Value>Crontab</Value>
|
||||||
|
<Value>Csv</Value>
|
||||||
|
<Value>Decapsulate</Value>
|
||||||
|
<Value>decapsulated</Value>
|
||||||
|
<Value>decapsulation</Value>
|
||||||
|
<Value>decrypter</Value>
|
||||||
|
<Value>Dequeue</Value>
|
||||||
|
<Value>dll</Value>
|
||||||
|
<Value>DynamORM</Value>
|
||||||
|
<Value>encrypter</Value>
|
||||||
|
<Value>enum</Value>
|
||||||
|
<Value>Enum</Value>
|
||||||
|
<Value>expando</Value>
|
||||||
|
<Value>fr</Value>
|
||||||
|
<Value>inequivalent</Value>
|
||||||
|
<Value>int</Value>
|
||||||
|
<Value>Int</Value>
|
||||||
|
<Value>Json</Value>
|
||||||
|
<Value>Linq</Value>
|
||||||
|
<Value>nd</Value>
|
||||||
|
<Value>Nullable</Value>
|
||||||
|
<Value>Prismo</Value>
|
||||||
|
<Value>queryable</Value>
|
||||||
|
<Value>Reinitialization</Value>
|
||||||
|
<Value>Remoting</Value>
|
||||||
|
<Value>Rijndael</Value>
|
||||||
|
<Value>rubyforge</Value>
|
||||||
|
<Value>singelton</Value>
|
||||||
|
<Value>th</Value>
|
||||||
|
<Value>tu</Value>
|
||||||
|
<Value>xmlns</Value>
|
||||||
|
</CollectionProperty>
|
||||||
|
</GlobalSettings>
|
||||||
|
<Analyzers>
|
||||||
|
<Analyzer AnalyzerId="StyleCop.CSharp.NamingRules">
|
||||||
|
<Rules>
|
||||||
|
<Rule Name="FieldNamesMustNotBeginWithUnderscore">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="FieldNamesMustNotContainUnderscore">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
</Rules>
|
||||||
|
<AnalyzerSettings>
|
||||||
|
<CollectionProperty Name="Hungarian">
|
||||||
|
<Value>en</Value>
|
||||||
|
<Value>il</Value>
|
||||||
|
<Value>is</Value>
|
||||||
|
<Value>on</Value>
|
||||||
|
<Value>ui</Value>
|
||||||
|
</CollectionProperty>
|
||||||
|
</AnalyzerSettings>
|
||||||
|
</Analyzer>
|
||||||
|
<Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">
|
||||||
|
<Rules>
|
||||||
|
<Rule Name="FileMustHaveHeader">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="FileHeaderMustShowCopyright">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="FileHeaderMustHaveCopyrightText">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="FileHeaderMustContainFileName">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="FileHeaderFileNameDocumentationMustMatchFileName">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="FileHeaderMustHaveValidCompanyText">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="DocumentationTextMustBeginWithACapitalLetter">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">True</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="DocumentationTextMustEndWithAPeriod">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">True</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="ElementDocumentationMustNotBeCopiedAndPasted">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
</Rules>
|
||||||
|
<AnalyzerSettings>
|
||||||
|
<BooleanProperty Name="IgnorePrivates">True</BooleanProperty>
|
||||||
|
<BooleanProperty Name="IgnoreInternals">True</BooleanProperty>
|
||||||
|
<BooleanProperty Name="IncludeFields">False</BooleanProperty>
|
||||||
|
</AnalyzerSettings>
|
||||||
|
</Analyzer>
|
||||||
|
<Analyzer AnalyzerId="StyleCop.CSharp.OrderingRules">
|
||||||
|
<Rules>
|
||||||
|
<Rule Name="UsingDirectivesMustBePlacedWithinNamespace">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="ElementsMustAppearInTheCorrectOrder">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="ElementsMustBeOrderedByAccess">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="StaticElementsMustAppearBeforeInstanceElements">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="ProtectedMustComeBeforeInternal">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
</Rules>
|
||||||
|
<AnalyzerSettings>
|
||||||
|
<BooleanProperty Name="GeneratedCodeElementOrder">False</BooleanProperty>
|
||||||
|
</AnalyzerSettings>
|
||||||
|
</Analyzer>
|
||||||
|
<Analyzer AnalyzerId="StyleCop.CSharp.LayoutRules">
|
||||||
|
<Rules>
|
||||||
|
<Rule Name="CurlyBracketsMustNotBeOmitted">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="ElementMustNotBeOnSingleLine">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="AllAccessorsMustBeMultiLineOrSingleLine">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="ElementsMustBeSeparatedByBlankLine">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
</Rules>
|
||||||
|
<AnalyzerSettings />
|
||||||
|
</Analyzer>
|
||||||
|
<Analyzer AnalyzerId="StyleCop.CSharp.ReadabilityRules">
|
||||||
|
<Rules>
|
||||||
|
<Rule Name="PrefixLocalCallsWithThis">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="ParameterMustFollowComma">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="SplitParametersMustStartOnLineAfterDeclaration">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="ParametersMustBeOnSameLineOrSeparateLines">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="ParameterMustNotSpanMultipleLines">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="DoNotPlaceRegionsWithinElements">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="CodeMustNotContainMultipleStatementsOnOneLine">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="BlockStatementsMustNotContainEmbeddedRegions">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="UseBuiltInTypeAlias">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
<Rule Name="PrefixCallsCorrectly">
|
||||||
|
<RuleSettings>
|
||||||
|
<BooleanProperty Name="Enabled">False</BooleanProperty>
|
||||||
|
</RuleSettings>
|
||||||
|
</Rule>
|
||||||
|
</Rules>
|
||||||
|
<AnalyzerSettings />
|
||||||
|
</Analyzer>
|
||||||
|
</Analyzers>
|
||||||
|
</StyleCopSettings>
|
||||||
Reference in New Issue
Block a user