This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Data;
|
||||
@@ -935,6 +936,7 @@ namespace DynamORM
|
||||
#region Internal fields and properties
|
||||
|
||||
private DbProviderFactory _provider;
|
||||
private DynamicProcedureInvoker _proc;
|
||||
private string _connectionString;
|
||||
private bool _singleConnection;
|
||||
private bool _singleTransaction;
|
||||
@@ -1006,6 +1008,23 @@ namespace DynamORM
|
||||
/// <summary>Gets the database provider.</summary>
|
||||
public DbProviderFactory Provider { get { return _provider; } }
|
||||
|
||||
/// <summary>Gets the procedures invoker.</summary>
|
||||
public dynamic Procedures
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_proc == null)
|
||||
{
|
||||
if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) != DynamicDatabaseOptions.SupportStoredProcedures)
|
||||
throw new InvalidOperationException("Database connection desn't support stored procedures.");
|
||||
|
||||
_proc = new DynamicProcedureInvoker(this);
|
||||
}
|
||||
|
||||
return _proc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets a value indicating whether
|
||||
/// dump commands to console or not.</summary>
|
||||
public bool DumpCommands { get; set; }
|
||||
@@ -2636,6 +2655,8 @@ namespace DynamORM
|
||||
}
|
||||
|
||||
ClearSchema();
|
||||
if (_proc != null)
|
||||
_proc.Dispose();
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
@@ -3007,7 +3028,14 @@ namespace DynamORM
|
||||
{
|
||||
if (args != null && args.Count() > 0)
|
||||
foreach (object item in args)
|
||||
{
|
||||
if (item is DynamicExpando)
|
||||
cmd.AddParameters(database, (DynamicExpando)item);
|
||||
else if (item is ExpandoObject)
|
||||
cmd.AddParameters(database, (ExpandoObject)item);
|
||||
else
|
||||
cmd.AddParameter(database, item);
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
@@ -4210,6 +4238,12 @@ namespace DynamORM
|
||||
return TypeMap.TryGetNullable(r.GetFieldType(i)) ?? DbType.String;
|
||||
}
|
||||
|
||||
internal static IEnumerable<dynamic> EnumerateReader(this IDataReader r)
|
||||
{
|
||||
while (r.Read())
|
||||
yield return r.RowToDynamic();
|
||||
}
|
||||
|
||||
#endregion IDataReader extensions
|
||||
|
||||
#region Mapper extensions
|
||||
@@ -4383,6 +4417,203 @@ namespace DynamORM
|
||||
#endregion Coalesce - besicaly not an extensions
|
||||
}
|
||||
|
||||
/// <summary>Dynamic procedure invoker.</summary>
|
||||
/// <remarks>Unfortunately I can use <c>out</c> and <c>ref</c> to
|
||||
/// return parameters, <see href="http://stackoverflow.com/questions/2475310/c-sharp-4-0-dynamic-doesnt-set-ref-out-arguments"/>.
|
||||
/// But see example for workaround. If there aren't any return parameters execution will return scalar value.
|
||||
/// Scalar result is not converted to provided generic type (if any). For output results there is possibility to map to provided class.
|
||||
/// </remarks><example>You still can use out, return and both way parameters by providing variable prefix:<code>
|
||||
/// dynamic res = db.Procedures.sp_Test_Scalar_In_Out(inp: Guid.NewGuid(), out_outp: Guid.Empty);
|
||||
/// Console.Out.WriteLine(res.outp);</code>
|
||||
/// Prefixes: <c>out_</c>, <c>ret_</c>, <c>both_</c>. Result will contain field without prefix.
|
||||
/// Here is an example with result class:<code>
|
||||
/// public class ProcResult { [Column("outp")] public Guid Output { get; set; } }
|
||||
/// ProcResult res4 = db.Procedures.sp_Test_Scalar_In_Out<ProcResult>(inp: Guid.NewGuid(), out_outp: Guid.Empty) as ProcResult;
|
||||
/// </code>As you can se, you can use mapper to do job for you.</example>
|
||||
public class DynamicProcedureInvoker : DynamicObject, IDisposable
|
||||
{
|
||||
private DynamicDatabase _db;
|
||||
|
||||
internal DynamicProcedureInvoker(DynamicDatabase db)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
|
||||
/// <summary>This is where the magic begins.</summary>
|
||||
/// <param name="binder">Binder to invoke.</param>
|
||||
/// <param name="args">Binder arguments.</param>
|
||||
/// <param name="result">Binder invoke result.</param>
|
||||
/// <returns>Returns <c>true</c> if invoke was performed.</returns>
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
||||
{
|
||||
// parse the method
|
||||
CallInfo info = binder.CallInfo;
|
||||
|
||||
// Get generic types
|
||||
IList<Type> types = binder.GetGenericTypeArguments();
|
||||
|
||||
Dictionary<string, int> retParams = null;
|
||||
|
||||
using (IDbConnection con = _db.Open())
|
||||
using (IDbCommand cmd = con.CreateCommand())
|
||||
{
|
||||
cmd.SetCommand(CommandType.StoredProcedure, binder.Name);
|
||||
|
||||
#region Prepare arguments
|
||||
|
||||
int alen = args.Length;
|
||||
if (alen > 0)
|
||||
{
|
||||
for (int i = 0; i < alen; i++)
|
||||
{
|
||||
object arg = args[i];
|
||||
|
||||
if (arg is DynamicExpando)
|
||||
cmd.AddParameters(_db, (DynamicExpando)arg);
|
||||
else if (arg is ExpandoObject)
|
||||
cmd.AddParameters(_db, (ExpandoObject)arg);
|
||||
else
|
||||
{
|
||||
if (info.ArgumentNames.Count > i && !string.IsNullOrEmpty(info.ArgumentNames[i]))
|
||||
{
|
||||
bool isOut = info.ArgumentNames[i].StartsWith("out_");
|
||||
bool isRet = info.ArgumentNames[i].StartsWith("ret_");
|
||||
bool isBoth = info.ArgumentNames[i].StartsWith("both_");
|
||||
string paramName = isOut || isRet ?
|
||||
info.ArgumentNames[i].Substring(4) :
|
||||
isBoth ? info.ArgumentNames[i].Substring(5) :
|
||||
info.ArgumentNames[i];
|
||||
|
||||
if (isOut || isBoth || isRet)
|
||||
{
|
||||
if (retParams == null)
|
||||
retParams = new Dictionary<string, int>();
|
||||
retParams.Add(paramName, cmd.Parameters.Count);
|
||||
}
|
||||
|
||||
cmd.AddParameter(
|
||||
_db.GetParameterName(paramName),
|
||||
isOut ? ParameterDirection.Output :
|
||||
isRet ? ParameterDirection.ReturnValue :
|
||||
isBoth ? ParameterDirection.InputOutput : ParameterDirection.Input,
|
||||
arg == null ? DbType.String : arg.GetType().ToDbType(), 0, isOut ? DBNull.Value : arg);
|
||||
}
|
||||
else
|
||||
cmd.AddParameter(_db, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Prepare arguments
|
||||
|
||||
#region Get main result
|
||||
|
||||
object mainResult = null;
|
||||
|
||||
if (types.Count > 0)
|
||||
{
|
||||
mainResult = types[0].GetDefaultValue();
|
||||
|
||||
if (types[0] == typeof(IDataReader))
|
||||
mainResult = cmd.ExecuteReader();
|
||||
else if (types[0].IsGenericEnumerable())
|
||||
{
|
||||
Type argType = types[0].GetGenericArguments().First();
|
||||
if (argType == typeof(object))
|
||||
using (IDataReader rdr = cmd.ExecuteReader())
|
||||
mainResult = rdr.EnumerateReader().ToList();
|
||||
else if (argType.IsValueType)
|
||||
{
|
||||
Type listType = typeof(List<>).MakeGenericType(new Type[] { argType });
|
||||
IList listInstance = (IList)Activator.CreateInstance(listType);
|
||||
|
||||
object defVal = listType.GetDefaultValue();
|
||||
|
||||
using (IDataReader rdr = cmd.ExecuteReader())
|
||||
while (rdr.Read())
|
||||
listInstance.Add(rdr[0] == DBNull.Value ? defVal : argType.CastObject(rdr[0]));
|
||||
|
||||
mainResult = listInstance;
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(argType);
|
||||
if (mapper == null)
|
||||
throw new InvalidCastException(string.Format("Don't konw what to do with this type: '{0}'.", argType.ToString()));
|
||||
|
||||
using (IDataReader rdr = cmd.ExecuteReader())
|
||||
mainResult = rdr.EnumerateReader().MapEnumerable(argType).ToList();
|
||||
}
|
||||
}
|
||||
else if (types[0].IsValueType)
|
||||
{
|
||||
mainResult = cmd.ExecuteScalar();
|
||||
if (mainResult != DBNull.Value)
|
||||
mainResult = types[0].CastObject(mainResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(types[0]);
|
||||
if (mapper == null)
|
||||
throw new InvalidCastException(string.Format("Don't konw what to do with this type: '{0}'.", types[0].ToString()));
|
||||
|
||||
using (IDataReader rdr = cmd.ExecuteReader())
|
||||
if (rdr.Read())
|
||||
mainResult = (rdr.ToDynamic() as object).Map(types[0]);
|
||||
else
|
||||
mainResult = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
mainResult = cmd.ExecuteNonQuery();
|
||||
|
||||
#endregion Get main result
|
||||
|
||||
#region Handle out params
|
||||
|
||||
if (retParams != null)
|
||||
{
|
||||
Dictionary<string, object> res = new Dictionary<string, object>();
|
||||
|
||||
if (mainResult != null)
|
||||
{
|
||||
if (mainResult == DBNull.Value)
|
||||
res.Add(binder.Name, null);
|
||||
else
|
||||
res.Add(binder.Name, mainResult);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, int> pos in retParams)
|
||||
res.Add(pos.Key, ((IDbDataParameter)cmd.Parameters[pos.Value]).Value);
|
||||
|
||||
if (types.Count > 1)
|
||||
{
|
||||
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(types[1]);
|
||||
|
||||
if (mapper != null)
|
||||
result = mapper.Create(res.ToDynamic());
|
||||
else
|
||||
result = res.ToDynamic();
|
||||
}
|
||||
else
|
||||
result = res.ToDynamic();
|
||||
}
|
||||
else
|
||||
result = mainResult;
|
||||
|
||||
#endregion Handle out params
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Dynamic query exception.</summary>
|
||||
[Serializable]
|
||||
public class DynamicQueryException : Exception, ISerializable
|
||||
@@ -11307,6 +11538,91 @@ namespace DynamORM
|
||||
#endregion Constructors
|
||||
}
|
||||
|
||||
/// <summary>Type cast helper.</summary>
|
||||
public static class DynamicCast
|
||||
{
|
||||
/// <summary>Gets the default value.</summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>Default instance.</returns>
|
||||
public static object GetDefaultValue(this Type type)
|
||||
{
|
||||
return type.IsValueType ? TypeDefaults.GetOrAdd(type, t => Activator.CreateInstance(t)) : null;
|
||||
}
|
||||
|
||||
/// <summary>Casts the object to this type.</summary>
|
||||
/// <param name="type">The type to which cast value.</param>
|
||||
/// <param name="val">The value to cast.</param>
|
||||
/// <returns>Value casted to new type.</returns>
|
||||
public static object CastObject(this Type type, object val)
|
||||
{
|
||||
return GetConverter(type, val)(val);
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<Type, object> TypeDefaults = new ConcurrentDictionary<Type, object>();
|
||||
private static readonly ConcurrentDictionary<Type, Func<object, object>> TypeAsCasts = new ConcurrentDictionary<Type, Func<object, object>>();
|
||||
private static readonly ConcurrentDictionary<PairOfTypes, Func<object, object>> TypeConvert = new ConcurrentDictionary<PairOfTypes, Func<object, object>>();
|
||||
private static readonly ParameterExpression ConvParameter = Expression.Parameter(typeof(object), "val");
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
private static Func<object, object> GetConverter(Type targetType, object val)
|
||||
{
|
||||
Func<object, object> fn;
|
||||
|
||||
if (!targetType.IsValueType && !val.GetType().IsValueType)
|
||||
{
|
||||
if (!TypeAsCasts.TryGetValue(targetType, out fn))
|
||||
{
|
||||
UnaryExpression instanceCast = Expression.TypeAs(ConvParameter, targetType);
|
||||
|
||||
fn = Expression.Lambda<Func<object, object>>(Expression.TypeAs(instanceCast, typeof(object)), ConvParameter).Compile();
|
||||
TypeAsCasts.AddOrUpdate(targetType, fn, (t, f) => fn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var fromType = val != null ? val.GetType() : typeof(object);
|
||||
var key = new PairOfTypes(fromType, targetType);
|
||||
if (TypeConvert.TryGetValue(key, out fn))
|
||||
return fn;
|
||||
|
||||
fn = (Func<object, object>)Expression.Lambda(Expression.Convert(Expression.Convert(Expression.Convert(ConvParameter, fromType), targetType), typeof(object)), ConvParameter).Compile();
|
||||
TypeConvert.AddOrUpdate(key, fn, (t, f) => fn);
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
private class PairOfTypes
|
||||
{
|
||||
private readonly Type _first;
|
||||
private readonly Type _second;
|
||||
|
||||
public PairOfTypes(Type first, Type second)
|
||||
{
|
||||
this._first = first;
|
||||
this._second = second;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (31 * _first.GetHashCode()) + _second.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
var other = obj as PairOfTypes;
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return _first.Equals(other._first)
|
||||
&& _second.Equals(other._second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Class with mapper cache.</summary>
|
||||
public static class DynamicMapperCache
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Some of methods in this code file is based on Kerosene ORM solution
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Some of methods in this code file is based on Kerosene ORM solution
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Some of methods in this code file is based on Kerosene ORM solution
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Some of methods in this code file is based on Kerosene ORM solution
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Some of methods in this code file is based on Kerosene ORM solution
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Some of methods in this code file is based on Kerosene ORM solution
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Some of methods in this code file is based on Kerosene ORM solution
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
<Compile Include="DynamicDatabase.cs" />
|
||||
<Compile Include="DynamicDatabaseOptions.cs" />
|
||||
<Compile Include="DynamicExtensions.cs" />
|
||||
<Compile Include="DynamicProcedureInvoker.cs" />
|
||||
<Compile Include="DynamicQueryException.cs" />
|
||||
<Compile Include="DynamicSchemaColumn.cs" />
|
||||
<Compile Include="DynamicTable.cs" />
|
||||
@@ -102,6 +103,7 @@
|
||||
<Compile Include="Mapper\DynamicTypeMap.cs" />
|
||||
<Compile Include="Mapper\IgnoreAttribute.cs" />
|
||||
<Compile Include="Mapper\TableAttribute.cs" />
|
||||
<Compile Include="Mapper\DynamicCast.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="DynamicExpando.cs" />
|
||||
<Compile Include="Helpers\IFinalizerDisposable.cs" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -47,6 +47,7 @@ namespace DynamORM
|
||||
#region Internal fields and properties
|
||||
|
||||
private DbProviderFactory _provider;
|
||||
private DynamicProcedureInvoker _proc;
|
||||
private string _connectionString;
|
||||
private bool _singleConnection;
|
||||
private bool _singleTransaction;
|
||||
@@ -118,6 +119,23 @@ namespace DynamORM
|
||||
/// <summary>Gets the database provider.</summary>
|
||||
public DbProviderFactory Provider { get { return _provider; } }
|
||||
|
||||
/// <summary>Gets the procedures invoker.</summary>
|
||||
public dynamic Procedures
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_proc == null)
|
||||
{
|
||||
if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) != DynamicDatabaseOptions.SupportStoredProcedures)
|
||||
throw new InvalidOperationException("Database connection desn't support stored procedures.");
|
||||
|
||||
_proc = new DynamicProcedureInvoker(this);
|
||||
}
|
||||
|
||||
return _proc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets a value indicating whether
|
||||
/// dump commands to console or not.</summary>
|
||||
public bool DumpCommands { get; set; }
|
||||
@@ -1748,6 +1766,8 @@ namespace DynamORM
|
||||
}
|
||||
|
||||
ClearSchema();
|
||||
if (_proc != null)
|
||||
_proc.Dispose();
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -210,7 +210,14 @@ namespace DynamORM
|
||||
{
|
||||
if (args != null && args.Count() > 0)
|
||||
foreach (object item in args)
|
||||
{
|
||||
if (item is DynamicExpando)
|
||||
cmd.AddParameters(database, (DynamicExpando)item);
|
||||
else if (item is ExpandoObject)
|
||||
cmd.AddParameters(database, (ExpandoObject)item);
|
||||
else
|
||||
cmd.AddParameter(database, item);
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
@@ -1413,6 +1420,12 @@ namespace DynamORM
|
||||
return TypeMap.TryGetNullable(r.GetFieldType(i)) ?? DbType.String;
|
||||
}
|
||||
|
||||
internal static IEnumerable<dynamic> EnumerateReader(this IDataReader r)
|
||||
{
|
||||
while (r.Read())
|
||||
yield return r.RowToDynamic();
|
||||
}
|
||||
|
||||
#endregion IDataReader extensions
|
||||
|
||||
#region Mapper extensions
|
||||
|
||||
236
DynamORM/DynamicProcedureInvoker.cs
Normal file
236
DynamORM/DynamicProcedureInvoker.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using DynamORM.Helpers;
|
||||
using DynamORM.Mapper;
|
||||
|
||||
namespace DynamORM
|
||||
{
|
||||
/// <summary>Dynamic procedure invoker.</summary>
|
||||
/// <remarks>Unfortunately I can use <c>out</c> and <c>ref</c> to
|
||||
/// return parameters, <see href="http://stackoverflow.com/questions/2475310/c-sharp-4-0-dynamic-doesnt-set-ref-out-arguments"/>.
|
||||
/// But see example for workaround. If there aren't any return parameters execution will return scalar value.
|
||||
/// Scalar result is not converted to provided generic type (if any). For output results there is possibility to map to provided class.
|
||||
/// </remarks><example>You still can use out, return and both way parameters by providing variable prefix:<code>
|
||||
/// dynamic res = db.Procedures.sp_Test_Scalar_In_Out(inp: Guid.NewGuid(), out_outp: Guid.Empty);
|
||||
/// Console.Out.WriteLine(res.outp);</code>
|
||||
/// Prefixes: <c>out_</c>, <c>ret_</c>, <c>both_</c>. Result will contain field without prefix.
|
||||
/// Here is an example with result class:<code>
|
||||
/// public class ProcResult { [Column("outp")] public Guid Output { get; set; } }
|
||||
/// ProcResult res4 = db.Procedures.sp_Test_Scalar_In_Out<ProcResult>(inp: Guid.NewGuid(), out_outp: Guid.Empty) as ProcResult;
|
||||
/// </code>As you can se, you can use mapper to do job for you.</example>
|
||||
public class DynamicProcedureInvoker : DynamicObject, IDisposable
|
||||
{
|
||||
private DynamicDatabase _db;
|
||||
|
||||
internal DynamicProcedureInvoker(DynamicDatabase db)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
|
||||
/// <summary>This is where the magic begins.</summary>
|
||||
/// <param name="binder">Binder to invoke.</param>
|
||||
/// <param name="args">Binder arguments.</param>
|
||||
/// <param name="result">Binder invoke result.</param>
|
||||
/// <returns>Returns <c>true</c> if invoke was performed.</returns>
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
||||
{
|
||||
// parse the method
|
||||
CallInfo info = binder.CallInfo;
|
||||
|
||||
// Get generic types
|
||||
IList<Type> types = binder.GetGenericTypeArguments();
|
||||
|
||||
Dictionary<string, int> retParams = null;
|
||||
|
||||
using (IDbConnection con = _db.Open())
|
||||
using (IDbCommand cmd = con.CreateCommand())
|
||||
{
|
||||
cmd.SetCommand(CommandType.StoredProcedure, binder.Name);
|
||||
|
||||
#region Prepare arguments
|
||||
|
||||
int alen = args.Length;
|
||||
if (alen > 0)
|
||||
{
|
||||
for (int i = 0; i < alen; i++)
|
||||
{
|
||||
object arg = args[i];
|
||||
|
||||
if (arg is DynamicExpando)
|
||||
cmd.AddParameters(_db, (DynamicExpando)arg);
|
||||
else if (arg is ExpandoObject)
|
||||
cmd.AddParameters(_db, (ExpandoObject)arg);
|
||||
else
|
||||
{
|
||||
if (info.ArgumentNames.Count > i && !string.IsNullOrEmpty(info.ArgumentNames[i]))
|
||||
{
|
||||
bool isOut = info.ArgumentNames[i].StartsWith("out_");
|
||||
bool isRet = info.ArgumentNames[i].StartsWith("ret_");
|
||||
bool isBoth = info.ArgumentNames[i].StartsWith("both_");
|
||||
string paramName = isOut || isRet ?
|
||||
info.ArgumentNames[i].Substring(4) :
|
||||
isBoth ? info.ArgumentNames[i].Substring(5) :
|
||||
info.ArgumentNames[i];
|
||||
|
||||
if (isOut || isBoth || isRet)
|
||||
{
|
||||
if (retParams == null)
|
||||
retParams = new Dictionary<string, int>();
|
||||
retParams.Add(paramName, cmd.Parameters.Count);
|
||||
}
|
||||
|
||||
cmd.AddParameter(
|
||||
_db.GetParameterName(paramName),
|
||||
isOut ? ParameterDirection.Output :
|
||||
isRet ? ParameterDirection.ReturnValue :
|
||||
isBoth ? ParameterDirection.InputOutput : ParameterDirection.Input,
|
||||
arg == null ? DbType.String : arg.GetType().ToDbType(), 0, isOut ? DBNull.Value : arg);
|
||||
}
|
||||
else
|
||||
cmd.AddParameter(_db, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Prepare arguments
|
||||
|
||||
#region Get main result
|
||||
|
||||
object mainResult = null;
|
||||
|
||||
if (types.Count > 0)
|
||||
{
|
||||
mainResult = types[0].GetDefaultValue();
|
||||
|
||||
if (types[0] == typeof(IDataReader))
|
||||
mainResult = cmd.ExecuteReader();
|
||||
else if (types[0].IsGenericEnumerable())
|
||||
{
|
||||
Type argType = types[0].GetGenericArguments().First();
|
||||
if (argType == typeof(object))
|
||||
using (IDataReader rdr = cmd.ExecuteReader())
|
||||
mainResult = rdr.EnumerateReader().ToList();
|
||||
else if (argType.IsValueType)
|
||||
{
|
||||
Type listType = typeof(List<>).MakeGenericType(new Type[] { argType });
|
||||
IList listInstance = (IList)Activator.CreateInstance(listType);
|
||||
|
||||
object defVal = listType.GetDefaultValue();
|
||||
|
||||
using (IDataReader rdr = cmd.ExecuteReader())
|
||||
while (rdr.Read())
|
||||
listInstance.Add(rdr[0] == DBNull.Value ? defVal : argType.CastObject(rdr[0]));
|
||||
|
||||
mainResult = listInstance;
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(argType);
|
||||
if (mapper == null)
|
||||
throw new InvalidCastException(string.Format("Don't konw what to do with this type: '{0}'.", argType.ToString()));
|
||||
|
||||
using (IDataReader rdr = cmd.ExecuteReader())
|
||||
mainResult = rdr.EnumerateReader().MapEnumerable(argType).ToList();
|
||||
}
|
||||
}
|
||||
else if (types[0].IsValueType)
|
||||
{
|
||||
mainResult = cmd.ExecuteScalar();
|
||||
if (mainResult != DBNull.Value)
|
||||
mainResult = types[0].CastObject(mainResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(types[0]);
|
||||
if (mapper == null)
|
||||
throw new InvalidCastException(string.Format("Don't konw what to do with this type: '{0}'.", types[0].ToString()));
|
||||
|
||||
using (IDataReader rdr = cmd.ExecuteReader())
|
||||
if (rdr.Read())
|
||||
mainResult = (rdr.ToDynamic() as object).Map(types[0]);
|
||||
else
|
||||
mainResult = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
mainResult = cmd.ExecuteNonQuery();
|
||||
|
||||
#endregion Get main result
|
||||
|
||||
#region Handle out params
|
||||
|
||||
if (retParams != null)
|
||||
{
|
||||
Dictionary<string, object> res = new Dictionary<string, object>();
|
||||
|
||||
if (mainResult != null)
|
||||
{
|
||||
if (mainResult == DBNull.Value)
|
||||
res.Add(binder.Name, null);
|
||||
else
|
||||
res.Add(binder.Name, mainResult);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, int> pos in retParams)
|
||||
res.Add(pos.Key, ((IDbDataParameter)cmd.Parameters[pos.Value]).Value);
|
||||
|
||||
if (types.Count > 1)
|
||||
{
|
||||
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(types[1]);
|
||||
|
||||
if (mapper != null)
|
||||
result = mapper.Create(res.ToDynamic());
|
||||
else
|
||||
result = res.ToDynamic();
|
||||
}
|
||||
else
|
||||
result = res.ToDynamic();
|
||||
}
|
||||
else
|
||||
result = mainResult;
|
||||
|
||||
#endregion Handle out params
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code file is based on Kerosene ORM solution for parsing dynamic
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
120
DynamORM/Mapper/DynamicCast.cs
Normal file
120
DynamORM/Mapper/DynamicCast.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace DynamORM.Mapper
|
||||
{
|
||||
/// <summary>Type cast helper.</summary>
|
||||
public static class DynamicCast
|
||||
{
|
||||
/// <summary>Gets the default value.</summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>Default instance.</returns>
|
||||
public static object GetDefaultValue(this Type type)
|
||||
{
|
||||
return type.IsValueType ? TypeDefaults.GetOrAdd(type, t => Activator.CreateInstance(t)) : null;
|
||||
}
|
||||
|
||||
/// <summary>Casts the object to this type.</summary>
|
||||
/// <param name="type">The type to which cast value.</param>
|
||||
/// <param name="val">The value to cast.</param>
|
||||
/// <returns>Value casted to new type.</returns>
|
||||
public static object CastObject(this Type type, object val)
|
||||
{
|
||||
return GetConverter(type, val)(val);
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<Type, object> TypeDefaults = new ConcurrentDictionary<Type, object>();
|
||||
private static readonly ConcurrentDictionary<Type, Func<object, object>> TypeAsCasts = new ConcurrentDictionary<Type, Func<object, object>>();
|
||||
private static readonly ConcurrentDictionary<PairOfTypes, Func<object, object>> TypeConvert = new ConcurrentDictionary<PairOfTypes, Func<object, object>>();
|
||||
private static readonly ParameterExpression ConvParameter = Expression.Parameter(typeof(object), "val");
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
private static Func<object, object> GetConverter(Type targetType, object val)
|
||||
{
|
||||
Func<object, object> fn;
|
||||
|
||||
if (!targetType.IsValueType && !val.GetType().IsValueType)
|
||||
{
|
||||
if (!TypeAsCasts.TryGetValue(targetType, out fn))
|
||||
{
|
||||
UnaryExpression instanceCast = Expression.TypeAs(ConvParameter, targetType);
|
||||
|
||||
fn = Expression.Lambda<Func<object, object>>(Expression.TypeAs(instanceCast, typeof(object)), ConvParameter).Compile();
|
||||
TypeAsCasts.AddOrUpdate(targetType, fn, (t, f) => fn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var fromType = val != null ? val.GetType() : typeof(object);
|
||||
var key = new PairOfTypes(fromType, targetType);
|
||||
if (TypeConvert.TryGetValue(key, out fn))
|
||||
return fn;
|
||||
|
||||
fn = (Func<object, object>)Expression.Lambda(Expression.Convert(Expression.Convert(Expression.Convert(ConvParameter, fromType), targetType), typeof(object)), ConvParameter).Compile();
|
||||
TypeConvert.AddOrUpdate(key, fn, (t, f) => fn);
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
private class PairOfTypes
|
||||
{
|
||||
private readonly Type _first;
|
||||
private readonly Type _second;
|
||||
|
||||
public PairOfTypes(Type first, Type second)
|
||||
{
|
||||
this._first = first;
|
||||
this._second = second;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (31 * _first.GetHashCode()) + _second.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
var other = obj as PairOfTypes;
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return _first.Equals(other._first)
|
||||
&& _second.Equals(other._second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,222 +1,46 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using DynamORM;
|
||||
using DynamORM.Mapper;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
|
||||
namespace Tester
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
[Table(Name = "mom_Sessions")]
|
||||
internal class Session
|
||||
{
|
||||
[Column(IsKey = true)]
|
||||
public virtual Guid ms_id { get; set; }
|
||||
|
||||
[Column]
|
||||
public virtual Guid ms_mus_id { get; set; }
|
||||
|
||||
[Column]
|
||||
public virtual long ms_last_activity { get; set; }
|
||||
|
||||
[Column]
|
||||
public virtual int ms_type { get; set; }
|
||||
|
||||
[Column]
|
||||
public virtual string ms_desc { get; set; }
|
||||
|
||||
[Ignore]
|
||||
public virtual string ms_did { get; set; }
|
||||
}
|
||||
|
||||
private static DynamORM.DynamicDatabase GetORM()
|
||||
{
|
||||
//return new DynamORM.DynamicDatabase(System.Data.SqlClient.SqlClientFactory.Instance,
|
||||
// "packet size=4096;User Id=sa;Password=sa123;data source=192.168.1.9,1433;initial catalog=MOM_SIERPC_WMS_TEST;",
|
||||
return new DynamORM.DynamicDatabase(System.Data.SqlClient.SqlClientFactory.Instance,
|
||||
"packet size=4096;User Id=sa;Password=Sa123;data source=192.168.1.9,1434;initial catalog=MAH_Melle-GAGARIN;",
|
||||
DynamORM.DynamicDatabaseOptions.SingleConnection | DynamORM.DynamicDatabaseOptions.SingleTransaction | DynamORM.DynamicDatabaseOptions.SupportStoredProcedures |
|
||||
DynamORM.DynamicDatabaseOptions.SupportSchema | DynamORM.DynamicDatabaseOptions.SupportTop);
|
||||
|
||||
//return new DynamORM.DynamicDatabase(System.Data.SQLite.SQLiteFactory.Instance,
|
||||
// "Data Source=test.db3;",
|
||||
// DynamORM.DynamicDatabaseOptions.SingleConnection | DynamORM.DynamicDatabaseOptions.SingleTransaction |
|
||||
// DynamORM.DynamicDatabaseOptions.SupportSchema | DynamORM.DynamicDatabaseOptions.SupportTop);
|
||||
return new DynamORM.DynamicDatabase(System.Data.SQLite.SQLiteFactory.Instance,
|
||||
"Data Source=test.db3;",
|
||||
DynamORM.DynamicDatabaseOptions.SingleConnection | DynamORM.DynamicDatabaseOptions.SingleTransaction |
|
||||
DynamORM.DynamicDatabaseOptions.SupportSchema | DynamORM.DynamicDatabaseOptions.SupportLimitOffset);
|
||||
// DynamORM.DynamicDatabaseOptions.SupportSchema | DynamORM.DynamicDatabaseOptions.SupportLimitOffset);
|
||||
}
|
||||
|
||||
public class ProcResult
|
||||
{
|
||||
[Column("sp_Test_Scalar_In_Out")]
|
||||
public Guid Result { get; set; }
|
||||
|
||||
[Column("outp")]
|
||||
public Guid Output { get; set; }
|
||||
}
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
using (var db = GetORM())
|
||||
using (var con = db.Open())
|
||||
using (var cmd = con.CreateCommand())
|
||||
new List<string>()
|
||||
{
|
||||
@"CREATE TABLE IF NOT EXISTS Test(id int NOT NULL PRIMARY KEY, val text);",
|
||||
@"DELETE FROM Test;",
|
||||
@"INSERT INTO Test VALUES(1, 'Test');",
|
||||
}.ForEach(x =>
|
||||
cmd.SetCommand(x)
|
||||
.ExecuteNonQuery());
|
||||
Guid res1 = db.Procedures.sp_Test_Scalar<Guid>();
|
||||
object res2 = db.Procedures.sp_Test_NonScalar();
|
||||
object res3 = db.Procedures.sp_Test_Scalar_In_Out<Guid>(inp: Guid.NewGuid(), out_outp: Guid.Empty);
|
||||
ProcResult res4 = db.Procedures.sp_Test_Scalar_In_Out<Guid, ProcResult>(inp: Guid.NewGuid(), out_outp: Guid.Empty);
|
||||
|
||||
Console.Out.WriteLine("Press ENTER to launch bombardment... or q and ENTER to quit.");
|
||||
while (Console.In.ReadLine() != "q")
|
||||
{
|
||||
Console.Out.WriteLine("Bombardment...");
|
||||
|
||||
long membefore = GC.GetTotalMemory(true);
|
||||
|
||||
BombsAway();
|
||||
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Mem Before: {0}, Mem After: {1}. Done.", membefore, GC.GetTotalMemory(true));
|
||||
}
|
||||
}
|
||||
|
||||
private static void BombsAway()
|
||||
{
|
||||
string test_str = string.Empty;
|
||||
|
||||
/*for (int y = 0; y < 10; y++)
|
||||
{
|
||||
string val = null;
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
dynamic o = new ExpandoObject();
|
||||
o.Test = "123";
|
||||
o.Test2 = 123;
|
||||
o.Test3 = true;
|
||||
o.Test4 = (object)null;
|
||||
|
||||
val = o.Test;
|
||||
val = o.Test2.ToString();
|
||||
}
|
||||
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Expr: [ExpandoObject only], Mem: {0}", GC.GetTotalMemory(true));
|
||||
}
|
||||
|
||||
for (int y = 0; y < 10; y++)
|
||||
{
|
||||
string val = null;
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
dynamic o = new ExpandoObject();
|
||||
var d = o as IDictionary<string, object>;
|
||||
d.Add("Test", "123");
|
||||
d.Add("Test2", 123);
|
||||
d.Add("Test3", true);
|
||||
d.Add("Test4", null);
|
||||
|
||||
val = o.Test;
|
||||
val = o.Test2.ToString();
|
||||
}
|
||||
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Expr: [ExpandoObject as Dict], Mem: {0}", GC.GetTotalMemory(true));
|
||||
}*/
|
||||
|
||||
/*for (int y = 0; y < 10; y++)
|
||||
{
|
||||
Func<dynamic, object> f = x => x.To == 0;
|
||||
for (int i = 0; i < 1000; i++)
|
||||
using (var p = DynamORM.Helpers.Dynamics.DynamicParser.Parse(f))
|
||||
test_str = p.ToString();
|
||||
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Expr: {0}, Mem: {1}", test_str, GC.GetTotalMemory(true));
|
||||
}*/
|
||||
|
||||
for (int y = 0; y < 10; y++)
|
||||
{
|
||||
using (var dbt = GetORM())
|
||||
using (dbt.Table("Test"))
|
||||
;
|
||||
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Expr: [Create and destroy ORM], Mem: {0}", GC.GetTotalMemory(true));
|
||||
}
|
||||
|
||||
//using (var db = GetORM())
|
||||
{
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
using (var db = GetORM())
|
||||
for (int i = 0; i < 1000; i++)
|
||||
test_str = ((int)db.Table("Test").Scalar("SELECT id FROM Test;")).ToString();
|
||||
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Expr: [db.Table(\"Test\").Scalar(\"SELECT id FROM Test;\")] = {0}, Mem: {1}", test_str, GC.GetTotalMemory(true));
|
||||
}
|
||||
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
using (var db = GetORM())
|
||||
for (int i = 0; i < 1000; i++)
|
||||
test_str = ((int)db.Table("Test").Scalar(columns: "id")).ToString();
|
||||
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Expr: [db.Table(\"Test\").Scalar(columns: \"id\")] = {0}, Mem: {1}", test_str, GC.GetTotalMemory(true));
|
||||
}
|
||||
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
using (var db = GetORM())
|
||||
for (int i = 0; i < 1000; i++)
|
||||
test_str = db.From(x => x.Test.As(x.t)).Where(t => t.id == 1).ToList().First().val;
|
||||
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Expr: [db.From(x => x.Test.As(x.t)).Where(t => t.id == 1).ToList().First().val] = {0}, Mem: {1}", test_str, GC.GetTotalMemory(true));
|
||||
}
|
||||
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
using (var db = GetORM())
|
||||
for (int i = 0; i < 1000; i++)
|
||||
test_str = ((int)db.From(x => x.Test.As(x.t)).Where(t => t.id == 1).Select(t => t.id).Scalar()).ToString();
|
||||
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Expr: [db.From(x => x.Test.As(x.t)).Where(t => t.id == 1).Select(t => t.id).Scalar()] = {0}, Mem: {1}", test_str, GC.GetTotalMemory(true));
|
||||
}
|
||||
}
|
||||
|
||||
/*for (int i = 0; i < 1000; i++)
|
||||
using (var db = GetORM())
|
||||
{
|
||||
//var session = db.From(x => x.mom_Sessions.As(x.s))
|
||||
// .Where(s => s.ms_id == Guid.Empty && s.ms_mus_id == Guid.Empty)
|
||||
// .Execute<Session>()
|
||||
// .FirstOrDefault();
|
||||
var session = db.From(x => x.mom_Sessions.As(x.s))
|
||||
.Where(s => s.ms_id == Guid.Empty && s.ms_mus_id == Guid.Empty)
|
||||
.Execute()
|
||||
.FirstOrDefault();
|
||||
|
||||
//db.Table("mom_Sessions").Delete()
|
||||
// .Where("ms_id", Guid.Empty)
|
||||
// .Where("ms_mus_id", Guid.Empty)
|
||||
// .Execute();
|
||||
|
||||
//var session = (db.Table().Query("SELECT * FROM mom_Sessions WHERE ms_id = @0 AND ms_mus_id = @1", Guid.Empty, Guid.Empty)
|
||||
// as IEnumerable<dynamic>).FirstOrDefault();
|
||||
}*/
|
||||
Console.Out.WriteLine(res1);
|
||||
Console.Out.WriteLine(res2);
|
||||
Console.Out.WriteLine(res3);
|
||||
Console.Out.WriteLine(res4.Output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user