- 增加 IQueryable RestoreToSelect 扩展方法,将 IQueryable 转回成 ISelect<T>;

This commit is contained in:
28810 2020-04-10 22:37:42 +08:00
parent 52fbe5ed86
commit 5e531b2521
10 changed files with 266 additions and 253 deletions

View File

@ -7,11 +7,21 @@
<member name="M:FreeSqlExtensionsLinqSql.AsQueryable``1(FreeSql.ISelect{``0})">
<summary>
将 ISelect&lt;T1&gt; 转换为 IQueryable&lt;T1&gt;<para></para>
此方法主要用于扩展比如abp IRepository GetAll() 接口方法需要返回 IQueryable 对象<para></para>
注意IQueryable 方法污染较为严重,请尽量避免此转换
用于扩展如abp IRepository GetAll() 接口方法需要返回 IQueryable 对象<para></para>
提示IQueryable 方法污染严重,查询功能的实现也不理想,应尽量避免此转换<para></para>
IQueryable&lt;T1&gt; 扩展方法 RestoreToSelect() 可以还原为 ISelect&lt;T1&gt;
</summary>
<returns></returns>
</member>
<member name="M:FreeSqlExtensionsLinqSql.RestoreToSelect``1(System.Linq.IQueryable{``0})">
<summary>
将 IQueryable&lt;T1&gt; 转换为 ISelect&lt;T1&gt;<para></para>
前提IQueryable 必须由 FreeSql.Extensions.Linq.QueryableProvider 实现
</summary>
<typeparam name="T1"></typeparam>
<param name="that"></param>
<returns></returns>
</member>
<member name="M:FreeSqlExtensionsLinqSql.Select``2(FreeSql.ISelect{``0},System.Linq.Expressions.Expression{System.Func{``0,``1}})">
<summary>
【linq to sql】专用扩展方法不建议直接使用

View File

@ -15,14 +15,27 @@ public static class FreeSqlExtensionsLinqSql
/// <summary>
/// 将 ISelect&lt;T1&gt; 转换为 IQueryable&lt;T1&gt;<para></para>
/// 此方法主要用于扩展比如abp IRepository GetAll() 接口方法需要返回 IQueryable 对象<para></para>
/// 注意IQueryable 方法污染较为严重,请尽量避免此转换
/// 用于扩展如abp IRepository GetAll() 接口方法需要返回 IQueryable 对象<para></para>
/// 提示IQueryable 方法污染严重,查询功能的实现也不理想,应尽量避免此转换<para></para>
/// IQueryable&lt;T1&gt; 扩展方法 RestoreToSelect() 可以还原为 ISelect&lt;T1&gt;
/// </summary>
/// <returns></returns>
public static IQueryable<T1> AsQueryable<T1>(this ISelect<T1> that) where T1 : class
{
return new QueryableProvider<T1, T1>(that as Select1Provider<T1>);
}
/// <summary>
/// 将 IQueryable&lt;T1&gt; 转换为 ISelect&lt;T1&gt;<para></para>
/// 前提IQueryable 必须由 FreeSql.Extensions.Linq.QueryableProvider 实现
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <param name="that"></param>
/// <returns></returns>
public static ISelect<T1> RestoreToSelect<T1>(this IQueryable<T1> that) where T1 : class
{
var queryable = that as QueryableProvider<T1, T1> ?? throw new Exception($"无法将 IQueryable<{typeof(T1).Name}> 转换为 ISelect<{typeof(T1).Name}>,因为他的实现不是 FreeSql.Extensions.Linq.QueryableProvider");
return queryable._select;
}
/// <summary>
/// 【linq to sql】专用扩展方法不建议直接使用

View File

@ -13,15 +13,15 @@ namespace FreeSql.Extensions.Linq
{
class QueryableProvider<TCurrent, TSource> : IQueryable<TCurrent>, IOrderedQueryable<TCurrent> where TSource : class
{
private Expression _expression;
private IQueryProvider _provider;
private Select1Provider<TSource> _select;
Expression _expression;
IQueryProvider _provider;
internal Select1Provider<TSource> _select;
public QueryableProvider(Select1Provider<TSource> select)
{
_select = select;
_expression = Expression.Constant(this);
_provider = new QueryProvider<TCurrent, TSource>(_select);
_provider = new QueryProvider<TCurrent, TSource>(_select, _expression);
}
public QueryableProvider(Expression expression, IQueryProvider provider, Select1Provider<TSource> select)
{
@ -49,56 +49,58 @@ namespace FreeSql.Extensions.Linq
class QueryProvider<TCurrent, TSource> : IQueryProvider where TSource : class
{
private Select1Provider<TSource> _select;
Select1Provider<TSource> _select;
Expression _oldExpression;
public QueryProvider(Select1Provider<TSource> select)
public QueryProvider(Select1Provider<TSource> select, Expression oldExpression)
{
_select = select;
_oldExpression = oldExpression;
}
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
ExecuteExp(expression, null, false);
if (typeof(TElement) != typeof(TCurrent))
return new QueryableProvider<TElement, TSource>(expression, new QueryProvider<TElement, TSource>(_select), _select);
return new QueryableProvider<TElement, TSource>(expression, new QueryProvider<TElement, TSource>(_select, expression), _select);
_oldExpression = expression;
return new QueryableProvider<TElement, TSource>(expression, this, _select);
}
public IQueryable CreateQuery(Expression expression) => throw new NotImplementedException();
public TResult Execute<TResult>(Expression expression)
{
var stackCallExps = new Stack<MethodCallExpression>();
var callExp = expression as MethodCallExpression;
while(callExp != null)
{
stackCallExps.Push(callExp);
callExp = callExp?.Arguments.FirstOrDefault() as MethodCallExpression;
return (TResult)ExecuteExp(expression, typeof(TResult), _oldExpression == expression);
}
public object Execute(Expression expression) => throw new NotImplementedException();
SelectGroupingProvider groupBy = null;
var isfirst = false;
while (stackCallExps.Any())
public object ExecuteExp(Expression expression, Type tresult, bool isProcessed)
{
callExp = stackCallExps.Pop();
TResult throwCallExp(string message) => throw new Exception($"FreeSql Queryable 解析出错,执行的方法 {callExp.Method.Name} {message}");
var callExp = expression as MethodCallExpression;
var isfirst = false;
if (callExp != null && isProcessed == false)
{
object throwCallExp(string message) => throw new Exception($"解析失败 {callExp.Method.Name} {message},提示:可以使用扩展方法 IQueryable.RestoreToSelect() 还原为 ISelect 再查询");
if (callExp.Method.DeclaringType != typeof(Queryable)) return throwCallExp($"必须属于 System.Linq.Queryable");
TResult tplMaxMinAvgSum(string method) {
object tplMaxMinAvgSum(string method)
{
if (callExp.Arguments.Count == 2)
{
var avgParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
return (TResult)Utils.GetDataReaderValue(typeof(TResult),
return Utils.GetDataReaderValue(tresult,
_select.GetType().GetMethod(method).MakeGenericMethod(avgParam.ReturnType).Invoke(_select, new object[] { avgParam }));
}
return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法");
}
TResult tplOrderBy(string method, bool isDescending)
object tplOrderBy(string method, bool isDescending)
{
if (callExp.Arguments.Count == 2)
{
var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
_select.OrderByReflection(arg1, isDescending);
return default(TResult);
return tresult.CreateInstanceGetDefaultValue();
}
return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法");
}
@ -106,7 +108,7 @@ namespace FreeSql.Extensions.Linq
{
case "Any":
if (callExp.Arguments.Count == 2) _select.InternalWhere(callExp.Arguments[1]);
return (TResult)(object)_select.Any();
return _select.Any();
case "AsQueryable":
break;
@ -123,12 +125,12 @@ namespace FreeSql.Extensions.Linq
var dywhere = callExp.Arguments[1].GetConstExprValue();
if (dywhere == null) return throwCallExp($" 参数值不能为 null");
_select.WhereDynamic(dywhere);
return (TResult)(object)_select.Any();
return _select.Any();
}
return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法");
case "Count":
if (callExp.Arguments.Count == 2) _select.InternalWhere(callExp.Arguments[1]);
return (TResult)Utils.GetDataReaderValue(typeof(TResult), _select.Count());
return Utils.GetDataReaderValue(tresult, _select.Count());
case "Distinct":
if (callExp.Arguments.Count == 1)
@ -170,8 +172,7 @@ namespace FreeSql.Extensions.Linq
var whereParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
if (whereParam.Parameters.Count == 1)
{
if (groupBy != null) groupBy.InternalHaving(whereParam);
else _select.InternalWhere(whereParam);
_select.InternalWhere(whereParam);
break;
}
return throwCallExp(" 不支持");
@ -185,7 +186,7 @@ namespace FreeSql.Extensions.Linq
case "ToList":
if (callExp.Arguments.Count == 1)
return (TResult)(object)_select.ToList();
return _select.ToList();
return throwCallExp(" 不支持");
case "Select":
@ -242,37 +243,21 @@ namespace FreeSql.Extensions.Linq
case "GroupBy":
return throwCallExp(" 不支持");
if (callExp.Arguments.Count == 2) //TODO: 待实现
{
var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
var map = new ReadAnonymousTypeInfo();
var field = new StringBuilder();
var index = -10000; //临时规则,不返回 as1
_select._commonExpression.ReadAnonymousField(_select._tables, field, map, ref index, arg1, null, _select._whereCascadeExpression, false); //不走 DTO 映射
var sql = field.ToString();
_select.GroupBy(sql.Length > 0 ? sql.Substring(2) : null);
groupBy = new SelectGroupingProvider(_select._orm, _select, map, sql, _select._commonExpression, _select._tables);
break;
}
return throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法");
default:
return throwCallExp(" 不支持");
}
}
if (tresult == null) return null;
if (isfirst)
{
_select.Limit(1);
if (_select._selectExpression != null)
return (TResult)(object)_select.InternalToList<TCurrent>(_select._selectExpression).FirstOrDefault();
return (TResult)(object)_select.ToList().FirstOrDefault();
return _select.InternalToList<TCurrent>(_select._selectExpression).FirstOrDefault();
return _select.ToList().FirstOrDefault();
}
if (_select._selectExpression != null)
return (TResult)(object)_select.InternalToList<TCurrent>(_select._selectExpression);
return (TResult)(object)_select.ToList();
}
public object Execute(Expression expression) => throw new NotImplementedException();
return _select.InternalToList<TCurrent>(_select._selectExpression);
return _select.ToList();
}
}
}

View File

@ -3,10 +3,8 @@ using System;
using System.Linq;
using Xunit;
namespace FreeSql.Tests.LinqToSql
namespace FreeSql.Tests.Linq
{
class TestLinqToSql
{
public Guid id { get; set; }
@ -29,7 +27,7 @@ namespace FreeSql.Tests.LinqToSql
public DateTime createtime { get; set; } = DateTime.Now;
}
public class SqliteLinqToSqlTests
public class ISelectLinqToSqlTests
{
[Fact]

View File

@ -58,29 +58,6 @@ namespace FreeSql.Tests.Linq
Assert.Equal(item.id, t1[0].id);
}
[Fact]
public void GroupBy()
{
//var item = new TestQueryableLinqToSql { name = Guid.NewGuid().ToString() };
//g.sqlite.Insert<TestQueryableLinqToSql>().AppendData(item).ExecuteAffrows();
//var t1 = (from a in g.sqlite.Select<TestQueryableLinqToSql>().AsQueryable()
// where a.id == item.id
// group a by new { a.id, a.name } into g
// select new
// {
// g.Key.id,
// g.Key.name,
// cou = g.Count(),
// avg = g.Average(x => x.click),
// sum = g.Sum(x => x.click),
// max = g.Max(x => x.click),
// min = g.Min(x => x.click)
// }).ToList();
//Assert.True(t1.Any());
//Assert.Equal(item.id, t1.First().id);
}
[Fact]
public void CaseWhen()
{

View File

@ -0,0 +1,50 @@
using FreeSql.DataAnnotations;
using FreeSql;
using System;
using System.Collections.Generic;
using Xunit;
using System.Linq;
using Newtonsoft.Json.Linq;
using NpgsqlTypes;
using Npgsql.LegacyPostgis;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.Threading;
using System.Data.SqlClient;
using kwlib;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace FreeSql.Tests.Linq
{
public class QueryableRestoreToSelectTest
{
class qt01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
[Navigate(nameof(qt01_item.qt01id))]
public List<qt01_item> items { get; set; }
}
class qt01_item
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string title { get; set; }
public int qt01id { get; set; }
}
IFreeSql fsql => g.sqlite;
[Fact]
public void RestoreToSelect()
{
Assert.Equal(fsql.Select<qt01>().Skip(2).First(a => a.name), fsql.Select<qt01>().AsQueryable().Skip(2).Take(1).RestoreToSelect().First(a => a.name));
Assert.Equal(fsql.Select<qt01>().Skip(2).First(a => new { a.name }).name, fsql.Select<qt01>().AsQueryable().Skip(2).Take(1).RestoreToSelect().First(a => new { a.name }).name);
}
}
}

View File

@ -214,7 +214,7 @@ public static partial class FreeSqlGlobalExtensions
}
/// <summary>
/// 将 IEnumable&lt;T&gt; 转成 ISelect&lt;T&gt;,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。
/// 将 IEnumable&lt;T&gt; 转成 ISelect&lt;T&gt;,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="that"></param>

View File

@ -2281,6 +2281,137 @@
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{System.Data.Common.DbDataReader,System.Threading.Tasks.Task},System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
查询若使用读写分离查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
</summary>
<param name="readerHander"></param>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{System.Data.Common.DbDataReader,System.Threading.Tasks.Task},System.String,System.Object)">
<summary>
查询ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
查询
</summary>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.String,System.Object)">
<summary>
查询ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
查询
</summary>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.String,System.Object)">
<summary>
查询ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
查询
</summary>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.String,System.Object)">
<summary>
查询ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.String,System.Object)">
<summary>
在【主库】执行ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.String,System.Object)">
<summary>
在【主库】执行ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 })
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.String,System.Object)">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > ?age", new { age = 25 })
</summary>
<typeparam name="T"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
<summary>
执行SQL返回对象集合Query&lt;User&gt;("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T1"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.String,System.Object)">
<summary>
执行SQL返回对象集合Query&lt;User&gt;("select * from user where age > ?age; select * from address", new { age = 25 })
</summary>
<typeparam name="T1"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<returns></returns>
</member>
<member name="E:FreeSql.IAop.ParseExpression">
<summary>
可自定义解析表达式
@ -2801,6 +2932,12 @@
<param name="timeout">超时</param>
<returns></returns>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.GetAsync">
<summary>
获取资源
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.Return(FreeSql.Internal.ObjectPool.Object{`0},System.Boolean)">
<summary>
使用完毕后,归还资源
@ -2871,6 +3008,12 @@
</summary>
<param name="obj">资源对象</param>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnGetAsync(FreeSql.Internal.ObjectPool.Object{`0})">
<summary>
从对象池获取对象成功的时候触发,通过该方法统计或初始化对象
</summary>
<param name="obj">资源对象</param>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnReturn(FreeSql.Internal.ObjectPool.Object{`0})">
<summary>
归还对象给对象池的时候触发
@ -3092,7 +3235,7 @@
</member>
<member name="M:FreeSqlGlobalExtensions.AsSelect``1(System.Collections.Generic.IEnumerable{``0})">
<summary>
将 IEnumable&lt;T&gt; 转成 ISelect&lt;T&gt;,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。
将 IEnumable&lt;T&gt; 转成 ISelect&lt;T&gt;,以便使用 FreeSql 的查询功能。此方法用于 Lambda 表达式中,快速进行集合导航的查询。
</summary>
<typeparam name="TEntity"></typeparam>
<param name="that"></param>
@ -3503,167 +3646,4 @@
</summary>
</member>
</members>
</doc>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Not``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean)">
<summary>
将 lambda 表达式取反
</summary>
<param name="exp"></param>
<param name="condition">true 时生效</param>
<returns></returns>
</member>
<member name="M:FreeUtil.NewMongodbId">
<summary>
生成类似Mongodb的ObjectId有序、不重复Guid
</summary>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1">
<summary>
插入数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(``0)">
<summary>
插入数据,传入实体
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(``0[])">
<summary>
插入数据,传入实体数组
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(System.Collections.Generic.List{``0})">
<summary>
插入数据,传入实体集合
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(System.Collections.Generic.IEnumerable{``0})">
<summary>
插入数据,传入实体集合
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Update``1">
<summary>
修改数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Update``1(System.Object)">
<summary>
修改数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Select``1">
<summary>
查询数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Select``1(System.Object)">
<summary>
查询数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Delete``1">
<summary>
删除数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Delete``1(System.Object)">
<summary>
删除数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Transaction(System.Action)">
<summary>
开启事务不支持异步60秒未执行完成可能被其他线程事务自动提交
</summary>
<param name="handler">事务体 () => {}</param>
</member>
<member name="M:IFreeSql.Transaction(System.TimeSpan,System.Action)">
<summary>
开启事务(不支持异步)
</summary>
<param name="timeout">超时,未执行完成(可能)被其他线程事务自动提交</param>
<param name="handler">事务体 () => {}</param>
</member>
<member name="M:IFreeSql.Transaction(System.Data.IsolationLevel,System.TimeSpan,System.Action)">
<summary>
开启事务(不支持异步)
</summary>
<param name="isolationLevel"></param>
<param name="handler">事务体 () => {}</param>
<param name="timeout">超时,未执行完成(可能)被其他线程事务自动提交</param>
</member>
<member name="P:IFreeSql.Ado">
<summary>
数据库访问对象
</summary>
</member>
<member name="P:IFreeSql.Aop">
<summary>
所有拦截方法都在这里
</summary>
</member>
<member name="P:IFreeSql.CodeFirst">
<summary>
CodeFirst 模式开发相关方法
</summary>
</member>
<member name="P:IFreeSql.DbFirst">
<summary>
DbFirst 模式开发相关方法
</summary>
</member>
<member name="P:IFreeSql.GlobalFilter">
<summary>
全局过滤设置,可默认附加为 Select/Update/Delete 条件
</summary>
</member>
</members>
</doc>