mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-08-25 10:08:11 +08:00
Add db.Storageable.WhereColumns(string [])
This commit is contained in:
parent
b48eaf41e0
commit
4a6046585f
@ -45,6 +45,8 @@ namespace OrmTest
|
|||||||
x2.BulkCopy();
|
x2.BulkCopy();
|
||||||
x2.BulkUpdate();
|
x2.BulkUpdate();
|
||||||
|
|
||||||
|
var x22 = db.Storageable<Order>(new Order() { Id = 0, Name = "jack" }).WhereColumns(new string[] { "Name" ,"Id"}).ExecuteCommand();
|
||||||
|
|
||||||
var dt = db.Queryable<Order>().Take(1).ToDataTable();
|
var dt = db.Queryable<Order>().Take(1).ToDataTable();
|
||||||
dt.TableName = "order";
|
dt.TableName = "order";
|
||||||
var addRow = dt.NewRow();
|
var addRow = dt.NewRow();
|
||||||
|
@ -291,6 +291,14 @@ namespace SqlSugar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IStorageable<T> WhereColumns(string [] columns)
|
||||||
|
{
|
||||||
|
var list = columns.Select(it=>this.Context.EntityMaintenance.GetDbColumnName<T>(it)).ToList();
|
||||||
|
var exp=ExpressionBuilderHelper.CreateNewFields<T>(this.Context.EntityMaintenance.GetEntityInfo<T>(), list);
|
||||||
|
return this.WhereColumns(exp);
|
||||||
|
}
|
||||||
|
|
||||||
private void SetConditList(List<StorageableInfo<T>> itemList, List<EntityColumnInfo> whereColumns, List<IConditionalModel> conditList)
|
private void SetConditList(List<StorageableInfo<T>> itemList, List<EntityColumnInfo> whereColumns, List<IConditionalModel> conditList)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
|
@ -19,6 +19,7 @@ namespace SqlSugar
|
|||||||
break;
|
break;
|
||||||
case ResolveExpressType.WhereMultiple:
|
case ResolveExpressType.WhereMultiple:
|
||||||
break;
|
break;
|
||||||
|
case ResolveExpressType.ArraySingle:
|
||||||
case ResolveExpressType.SelectSingle:
|
case ResolveExpressType.SelectSingle:
|
||||||
Select(expression, parameter, true);
|
Select(expression, parameter, true);
|
||||||
break;
|
break;
|
||||||
|
@ -9,6 +9,7 @@ namespace SqlSugar
|
|||||||
public interface IStorageable<T> where T : class, new()
|
public interface IStorageable<T> where T : class, new()
|
||||||
{
|
{
|
||||||
IStorageable<T> WhereColumns(Expression<Func<T, object>> columns);
|
IStorageable<T> WhereColumns(Expression<Func<T, object>> columns);
|
||||||
|
IStorageable<T> WhereColumns(string [] columns);
|
||||||
IStorageable<T> SplitInsert(Func<StorageableInfo<T>, bool> conditions, string message=null);
|
IStorageable<T> SplitInsert(Func<StorageableInfo<T>, bool> conditions, string message=null);
|
||||||
IStorageable<T> SplitUpdate(Func<StorageableInfo<T>, bool> conditions, string message = null);
|
IStorageable<T> SplitUpdate(Func<StorageableInfo<T>, bool> conditions, string message = null);
|
||||||
IStorageable<T> Saveable(string inserMessage = null, string updateMessage = null);
|
IStorageable<T> Saveable(string inserMessage = null, string updateMessage = null);
|
||||||
|
@ -261,6 +261,7 @@
|
|||||||
<Compile Include="Abstract\SugarProvider\SqlSugarScopeProvider.cs" />
|
<Compile Include="Abstract\SugarProvider\SqlSugarScopeProvider.cs" />
|
||||||
<Compile Include="Utilities\CallContext.cs" />
|
<Compile Include="Utilities\CallContext.cs" />
|
||||||
<Compile Include="Utilities\CallContextAsync.cs" />
|
<Compile Include="Utilities\CallContextAsync.cs" />
|
||||||
|
<Compile Include="Utilities\ExpressionBuilderHelper.cs" />
|
||||||
<Compile Include="Utilities\CommonExtensions.cs" />
|
<Compile Include="Utilities\CommonExtensions.cs" />
|
||||||
<Compile Include="Utilities\PropertyCallAdapterProvider.cs" />
|
<Compile Include="Utilities\PropertyCallAdapterProvider.cs" />
|
||||||
<Compile Include="Utilities\SugarRetry.cs" />
|
<Compile Include="Utilities\SugarRetry.cs" />
|
||||||
|
116
Src/Asp.Net/SqlSugar/Utilities/ExpressionBuilderHelper.cs
Normal file
116
Src/Asp.Net/SqlSugar/Utilities/ExpressionBuilderHelper.cs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SqlSugar
|
||||||
|
{
|
||||||
|
public class ExpressionBuilderHelper
|
||||||
|
{
|
||||||
|
public static Expression<Func<T, object>> CreateNewFields<T>(EntityInfo entity,List<string> propertyNames)
|
||||||
|
{
|
||||||
|
Type sourceType = typeof(T);
|
||||||
|
Dictionary<string, PropertyInfo> sourceProperties = entity.Columns.Where(it=> propertyNames.Contains(it.PropertyName)).ToDictionary(it=>it.PropertyName,it=>it.PropertyInfo);
|
||||||
|
|
||||||
|
Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicType(sourceProperties.Values);
|
||||||
|
|
||||||
|
ParameterExpression sourceItem = Expression.Parameter(sourceType, "t");
|
||||||
|
IEnumerable<MemberBinding> bindings = dynamicType.GetRuntimeProperties().Select(p => Expression.Bind(p, Expression.Property(sourceItem, sourceProperties[p.Name]))).OfType<MemberBinding>();
|
||||||
|
|
||||||
|
return Expression.Lambda<Func<T, object>>(Expression.MemberInit(
|
||||||
|
Expression.New(dynamicType.GetConstructor(Type.EmptyTypes)), bindings), sourceItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal static class LinqRuntimeTypeBuilder
|
||||||
|
{
|
||||||
|
private static readonly AssemblyName AssemblyName = new AssemblyName() { Name = "LinqRuntimeTypes4iTheoChan" };
|
||||||
|
private static readonly ModuleBuilder ModuleBuilder;
|
||||||
|
private static readonly Dictionary<string, Type> BuiltTypes = new Dictionary<string, Type>();
|
||||||
|
|
||||||
|
static LinqRuntimeTypeBuilder()
|
||||||
|
{
|
||||||
|
ModuleBuilder = AssemblyBuilder.DefineDynamicAssembly(AssemblyName, AssemblyBuilderAccess.Run).DefineDynamicModule(AssemblyName.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetTypeKey(Dictionary<string, Type> properties)
|
||||||
|
{
|
||||||
|
//TODO: optimize the type caching -- if fields are simply reordered, that doesn't mean that they're actually different types, so this needs to be smarter
|
||||||
|
string key = string.Empty;
|
||||||
|
foreach (var prop in properties)
|
||||||
|
key += prop.Key + ";" + prop.Value.Name + ";";
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
private const MethodAttributes RuntimeGetSetAttrs = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
|
||||||
|
|
||||||
|
public static Type BuildDynamicType(Dictionary<string, Type> properties)
|
||||||
|
{
|
||||||
|
if (null == properties)
|
||||||
|
throw new ArgumentNullException(nameof(properties));
|
||||||
|
if (0 == properties.Count)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(properties), "fields must have at least 1 field definition");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Acquires an exclusive lock on the specified object.
|
||||||
|
Monitor.Enter(BuiltTypes);
|
||||||
|
string className = GetTypeKey(properties);
|
||||||
|
|
||||||
|
if (BuiltTypes.ContainsKey(className))
|
||||||
|
return BuiltTypes[className];
|
||||||
|
|
||||||
|
TypeBuilder typeBdr = ModuleBuilder.DefineType(className, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable);
|
||||||
|
|
||||||
|
foreach (var prop in properties)
|
||||||
|
{
|
||||||
|
var propertyBdr = typeBdr.DefineProperty(name: prop.Key, attributes: PropertyAttributes.None, returnType: prop.Value, parameterTypes: null);
|
||||||
|
var fieldBdr = typeBdr.DefineField("itheofield_" + prop.Key, prop.Value, FieldAttributes.Private);
|
||||||
|
|
||||||
|
MethodBuilder getMethodBdr = typeBdr.DefineMethod("get_" + prop.Key, RuntimeGetSetAttrs, prop.Value, Type.EmptyTypes);
|
||||||
|
ILGenerator getIL = getMethodBdr.GetILGenerator();
|
||||||
|
getIL.Emit(OpCodes.Ldarg_0);
|
||||||
|
getIL.Emit(OpCodes.Ldfld, fieldBdr);
|
||||||
|
getIL.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
MethodBuilder setMethodBdr = typeBdr.DefineMethod("set_" + prop.Key, RuntimeGetSetAttrs, null, new Type[] { prop.Value });
|
||||||
|
ILGenerator setIL = setMethodBdr.GetILGenerator();
|
||||||
|
setIL.Emit(OpCodes.Ldarg_0);
|
||||||
|
setIL.Emit(OpCodes.Ldarg_1);
|
||||||
|
setIL.Emit(OpCodes.Stfld, fieldBdr);
|
||||||
|
setIL.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
propertyBdr.SetGetMethod(getMethodBdr);
|
||||||
|
propertyBdr.SetSetMethod(setMethodBdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
BuiltTypes[className] = typeBdr.CreateType();
|
||||||
|
|
||||||
|
return BuiltTypes[className];
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Monitor.Exit(BuiltTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetTypeKey(IEnumerable<PropertyInfo> properties)
|
||||||
|
{
|
||||||
|
return GetTypeKey(properties.ToDictionary(f => f.Name, f => f.PropertyType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type GetDynamicType(IEnumerable<PropertyInfo> properties)
|
||||||
|
{
|
||||||
|
return BuildDynamicType(properties.ToDictionary(f => f.Name, f => f.PropertyType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user