mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 增加 IEnumerable<TEntity> 扩展方法 AsSelect
This commit is contained in:
parent
fccc3fc8b9
commit
23d5d33bdd
@ -196,6 +196,22 @@ namespace FreeSql.Tests.MySql {
|
|||||||
var count = select.Where(a => 1 == 1).Count();
|
var count = select.Where(a => 1 == 1).Count();
|
||||||
Assert.False(select.Where(a => 1 == 2).Any());
|
Assert.False(select.Where(a => 1 == 2).Any());
|
||||||
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
||||||
|
|
||||||
|
var sql2222 = select.Where(a =>
|
||||||
|
select.Where(b => b.Id == a.Id &&
|
||||||
|
select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id)
|
||||||
|
.Offset(a.Id)
|
||||||
|
.Any()
|
||||||
|
).Any(c => c.Id == a.Id + 10)
|
||||||
|
);
|
||||||
|
var sql2222Tolist = sql2222.ToList();
|
||||||
|
|
||||||
|
var collectionSelect = select.Where(a =>
|
||||||
|
a.Type.Guid == a.TestTypeInfoGuid &&
|
||||||
|
a.Type.Parent.Id == a.Type.ParentId &&
|
||||||
|
a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id)
|
||||||
|
);
|
||||||
|
collectionSelect.ToList();
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Count() {
|
public void Count() {
|
||||||
|
@ -70,6 +70,22 @@ namespace FreeSql.Tests.Oracle {
|
|||||||
var count = select.Where(a => 1 == 1).Count();
|
var count = select.Where(a => 1 == 1).Count();
|
||||||
Assert.False(select.Where(a => 1 == 2).Any());
|
Assert.False(select.Where(a => 1 == 2).Any());
|
||||||
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
||||||
|
|
||||||
|
var sql2222 = select.Where(a =>
|
||||||
|
select.Where(b => b.Id == a.Id &&
|
||||||
|
select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id)
|
||||||
|
.Offset(a.Id)
|
||||||
|
.Any()
|
||||||
|
).Any(c => c.Id == a.Id + 10)
|
||||||
|
);
|
||||||
|
var sql2222Tolist = sql2222.ToList();
|
||||||
|
|
||||||
|
var collectionSelect = select.Where(a =>
|
||||||
|
a.Type.Guid == a.TestTypeInfoGuid &&
|
||||||
|
a.Type.Parent.Id == a.Type.ParentId &&
|
||||||
|
a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id)
|
||||||
|
);
|
||||||
|
collectionSelect.ToList();
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Count() {
|
public void Count() {
|
||||||
|
@ -138,6 +138,22 @@ namespace FreeSql.Tests.PostgreSQL {
|
|||||||
var count = select.Where(a => 1 == 1).Count();
|
var count = select.Where(a => 1 == 1).Count();
|
||||||
Assert.False(select.Where(a => 1 == 2).Any());
|
Assert.False(select.Where(a => 1 == 2).Any());
|
||||||
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
||||||
|
|
||||||
|
var sql2222 = select.Where(a =>
|
||||||
|
select.Where(b => b.Id == a.Id &&
|
||||||
|
select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id)
|
||||||
|
.Offset(a.Id)
|
||||||
|
.Any()
|
||||||
|
).Any(c => c.Id == a.Id + 10)
|
||||||
|
);
|
||||||
|
var sql2222Tolist = sql2222.ToList();
|
||||||
|
|
||||||
|
var collectionSelect = select.Where(a =>
|
||||||
|
a.Type.Guid == a.TestTypeInfoGuid &&
|
||||||
|
a.Type.Parent.Id == a.Type.ParentId &&
|
||||||
|
a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id)
|
||||||
|
);
|
||||||
|
collectionSelect.ToList();
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Count() {
|
public void Count() {
|
||||||
|
@ -71,6 +71,22 @@ namespace FreeSql.Tests.SqlServer {
|
|||||||
var count = select.Where(a => 1 == 1).Count();
|
var count = select.Where(a => 1 == 1).Count();
|
||||||
Assert.False(select.Where(a => 1 == 2).Any());
|
Assert.False(select.Where(a => 1 == 2).Any());
|
||||||
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
||||||
|
|
||||||
|
var sql2222 = select.Where(a =>
|
||||||
|
select.Where(b => b.Id == a.Id &&
|
||||||
|
select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id)
|
||||||
|
.Offset(a.Id)
|
||||||
|
.Any()
|
||||||
|
).Any(c => c.Id == a.Id + 10)
|
||||||
|
);
|
||||||
|
var sql2222Tolist = sql2222.ToList();
|
||||||
|
|
||||||
|
var collectionSelect = select.Where(a =>
|
||||||
|
a.Type.Guid == a.TestTypeInfoGuid &&
|
||||||
|
a.Type.Parent.Id == a.Type.ParentId &&
|
||||||
|
a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id)
|
||||||
|
);
|
||||||
|
collectionSelect.ToList();
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Count() {
|
public void Count() {
|
||||||
|
@ -102,6 +102,22 @@ namespace FreeSql.Tests.Sqlite {
|
|||||||
var count = select.Where(a => 1 == 1).Count();
|
var count = select.Where(a => 1 == 1).Count();
|
||||||
Assert.False(select.Where(a => 1 == 2).Any());
|
Assert.False(select.Where(a => 1 == 2).Any());
|
||||||
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
Assert.Equal(count > 0, select.Where(a => 1 == 1).Any());
|
||||||
|
|
||||||
|
var sql2222 = select.Where(a =>
|
||||||
|
select.Where(b => b.Id == a.Id &&
|
||||||
|
select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id)
|
||||||
|
.Offset(a.Id)
|
||||||
|
.Any()
|
||||||
|
).Any(c => c.Id == a.Id + 10)
|
||||||
|
);
|
||||||
|
var sql2222Tolist = sql2222.ToList();
|
||||||
|
|
||||||
|
var collectionSelect = select.Where(a =>
|
||||||
|
a.Type.Guid == a.TestTypeInfoGuid &&
|
||||||
|
a.Type.Parent.Id == a.Type.ParentId &&
|
||||||
|
a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id)
|
||||||
|
);
|
||||||
|
collectionSelect.ToList();
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Count() {
|
public void Count() {
|
||||||
|
@ -27,15 +27,22 @@ namespace FreeSql.Tests {
|
|||||||
public virtual Order Order { get; set; }
|
public virtual Order Order { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
class NullAggreTestTable {
|
|
||||||
[Column(IsIdentity = true)]
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
ISelect<TestInfo> select => g.mysql.Select<TestInfo>();
|
ISelect<TestInfo> select => g.mysql.Select<TestInfo>();
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Test1() {
|
public void Test1() {
|
||||||
|
|
||||||
|
var collSelect1 = g.mysql.Select<Order>().Where(a =>
|
||||||
|
a.OrderDetails.AsSelect().Where(b => b.OrderId == a.OrderID).Any()
|
||||||
|
);
|
||||||
|
|
||||||
|
var collectionSelect = select.Where(a =>
|
||||||
|
a.Type.Guid == a.TypeGuid &&
|
||||||
|
a.Type.Parent.Id == a.Type.ParentId &&
|
||||||
|
a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var order = g.mysql.Select<Order>().Where(a => a.OrderID == 1).ToOne(); //查询订单表
|
var order = g.mysql.Select<Order>().Where(a => a.OrderID == 1).ToOne(); //查询订单表
|
||||||
var orderDetail1 = order.OrderDetails; //第一次访问,查询数据库
|
var orderDetail1 = order.OrderDetails; //第一次访问,查询数据库
|
||||||
var orderDetail2 = order.OrderDetails; //第二次访问,不查
|
var orderDetail2 = order.OrderDetails; //第二次访问,不查
|
||||||
@ -182,6 +189,11 @@ namespace FreeSql.Tests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class NullAggreTestTable {
|
||||||
|
[Column(IsIdentity = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Table(Name = "xxx", SelectFilter = " a.id > 0")]
|
[Table(Name = "xxx", SelectFilter = " a.id > 0")]
|
||||||
class TestInfo {
|
class TestInfo {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using FreeSql;
|
||||||
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@ -73,4 +74,17 @@ public static class FreeSqlGlobalExtensions {
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 IEnumable<T> 转成 ISelect<T>,以便使用 FreeSql 的查询功能。此方法用于 Lambad 表达式中,快速进行集合导航的查询。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEntity"></typeparam>
|
||||||
|
/// <param name="that"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ISelect<TEntity> AsSelect<TEntity>(this IEnumerable<TEntity> that) where TEntity : class {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
public static ISelect<TEntity> AsSelect<TEntity>(this IEnumerable<TEntity> that, IFreeSql orm = null) where TEntity : class {
|
||||||
|
return orm?.Select<TEntity>();
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
using FreeSql.Internal.Model;
|
using FreeSql.Internal.Model;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -236,12 +237,18 @@ namespace FreeSql.Internal {
|
|||||||
}
|
}
|
||||||
if (callType.FullName.StartsWith("FreeSql.ISelect`")) { //子表查询
|
if (callType.FullName.StartsWith("FreeSql.ISelect`")) { //子表查询
|
||||||
if (exp3.Method.Name == "Any") { //exists
|
if (exp3.Method.Name == "Any") { //exists
|
||||||
|
var anyArgs = exp3.Arguments;
|
||||||
var exp3Stack = new Stack<Expression>();
|
var exp3Stack = new Stack<Expression>();
|
||||||
var exp3tmp = exp3.Object;
|
var exp3tmp = exp3.Object;
|
||||||
|
if (exp3tmp != null && anyArgs.Any())
|
||||||
|
exp3Stack.Push(Expression.Call(exp3tmp, callType.GetMethod("Where", anyArgs.Select(a => a.Type).ToArray()), anyArgs.ToArray()));
|
||||||
while (exp3tmp != null) {
|
while (exp3tmp != null) {
|
||||||
exp3Stack.Push(exp3tmp);
|
exp3Stack.Push(exp3tmp);
|
||||||
switch (exp3tmp.NodeType) {
|
switch (exp3tmp.NodeType) {
|
||||||
case ExpressionType.Call: exp3tmp = (exp3tmp as MethodCallExpression).Object; continue;
|
case ExpressionType.Call:
|
||||||
|
var exp3tmpCall = (exp3tmp as MethodCallExpression);
|
||||||
|
exp3tmp = exp3tmpCall.Object == null ? exp3tmpCall.Arguments.FirstOrDefault() : exp3tmpCall.Object;
|
||||||
|
continue;
|
||||||
case ExpressionType.MemberAccess: exp3tmp = (exp3tmp as MemberExpression).Expression; continue;
|
case ExpressionType.MemberAccess: exp3tmp = (exp3tmp as MemberExpression).Expression; continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -253,7 +260,19 @@ namespace FreeSql.Internal {
|
|||||||
while (exp3Stack.Any()) {
|
while (exp3Stack.Any()) {
|
||||||
exp3tmp = exp3Stack.Pop();
|
exp3tmp = exp3Stack.Pop();
|
||||||
if (exp3tmp.Type.FullName.StartsWith("FreeSql.ISelect`") && fsql == null) {
|
if (exp3tmp.Type.FullName.StartsWith("FreeSql.ISelect`") && fsql == null) {
|
||||||
fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke();
|
if (exp3tmp.NodeType == ExpressionType.Call) {
|
||||||
|
var exp3tmpCall = (exp3tmp as MethodCallExpression);
|
||||||
|
if (exp3tmpCall.Method.Name == "AsSelect" && exp3tmpCall.Object == null) {
|
||||||
|
var exp3tmpArg1Type = exp3tmpCall.Arguments.FirstOrDefault()?.Type;
|
||||||
|
if (exp3tmpArg1Type != null) {
|
||||||
|
var exp3tmpEleType = exp3tmpArg1Type.GetElementType() ?? exp3tmpArg1Type.GenericTypeArguments.FirstOrDefault();
|
||||||
|
if (exp3tmpEleType != null) {
|
||||||
|
fsql = typeof(IFreeSql).GetMethod("Select", new Type[0]).MakeGenericMethod(exp3tmpEleType).Invoke(_common._orm, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke();
|
||||||
fsqlType = fsql?.GetType();
|
fsqlType = fsql?.GetType();
|
||||||
if (fsqlType == null) break;
|
if (fsqlType == null) break;
|
||||||
fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1);
|
fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1);
|
||||||
@ -295,6 +314,12 @@ namespace FreeSql.Internal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var eleType = callType.GetElementType() ?? callType.GenericTypeArguments.FirstOrDefault();
|
||||||
|
if (eleType != null && typeof(IEnumerable<>).MakeGenericType(eleType).IsAssignableFrom(callType)) { //集合导航属性子查询
|
||||||
|
if (exp3.Method.Name == "Any") { //exists
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
var other3Exp = ExpressionLambdaToSqlOther(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
var other3Exp = ExpressionLambdaToSqlOther(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp;
|
if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp;
|
||||||
throw new Exception($"未实现函数表达式 {exp3} 解析");
|
throw new Exception($"未实现函数表达式 {exp3} 解析");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user