mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	@@ -23,7 +23,7 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace base_entity
 | 
					namespace base_entity
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    class Program
 | 
					    static class Program
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        class TestConfig
 | 
					        class TestConfig
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -196,6 +196,17 @@ namespace base_entity
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            fsql.UseJsonMap();
 | 
					            fsql.UseJsonMap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //var txt1 = fsql.Ado.Query<(string, string)>("select '꧁꫞꯭丑小鸭꫞꧂', '123123中国人' from dual");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fsql.Insert(new Order { ShippingAddress = "'꧁꫞꯭丑小鸭꫞꧂'" }).ExecuteAffrows();
 | 
				
			||||||
 | 
					            fsql.Insert(new Order { ShippingAddress = "'123123中国人'" }).ExecuteAffrows();
 | 
				
			||||||
 | 
					            var lst1 = fsql.Select<Order>().ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var lst2 = fsql.Select<Order>().ToListIgnore(a => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                a.ShippingAddress
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            fsql.Delete<TopicMapTypeToListDto>().Where("1=1").ExecuteAffrows();
 | 
					            fsql.Delete<TopicMapTypeToListDto>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
            fsql.Insert(new[]
 | 
					            fsql.Insert(new[]
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -794,5 +805,48 @@ namespace base_entity
 | 
				
			|||||||
            Console.WriteLine("按任意键结束。。。");
 | 
					            Console.WriteLine("按任意键结束。。。");
 | 
				
			||||||
            Console.ReadKey();
 | 
					            Console.ReadKey();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static List<T1> ToListIgnore<T1>(this ISelect<T1> that, Expression<Func<T1, object>> selector)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (selector == null) return that.ToList();
 | 
				
			||||||
 | 
					            var s0p = that as Select0Provider;
 | 
				
			||||||
 | 
					            var tb = s0p._tables[0];
 | 
				
			||||||
 | 
					            var parmExp = tb.Parameter ?? Expression.Parameter(tb.Table.Type, tb.Alias);
 | 
				
			||||||
 | 
					            var initExps = tb.Table.Columns.Values
 | 
				
			||||||
 | 
					                .Where(a => a.Attribute.IsIgnore == false)
 | 
				
			||||||
 | 
					                .Select(a => new
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    exp = Expression.Bind(tb.Table.Properties[a.CsName], Expression.MakeMemberAccess(parmExp, tb.Table.Properties[a.CsName])),
 | 
				
			||||||
 | 
					                    ignored = TestMemberExpressionVisitor.IsExists(selector, Expression.MakeMemberAccess(parmExp, tb.Table.Properties[a.CsName]))
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .Where(a => a.ignored == false)
 | 
				
			||||||
 | 
					                .Select(a => a.exp)
 | 
				
			||||||
 | 
					                .ToArray();
 | 
				
			||||||
 | 
					            var lambda = Expression.Lambda<Func<T1, T1>>(
 | 
				
			||||||
 | 
					                Expression.MemberInit(
 | 
				
			||||||
 | 
					                    Expression.New(tb.Table.Type),
 | 
				
			||||||
 | 
					                    initExps
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                parmExp
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            return that.ToList(lambda);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class TestMemberExpressionVisitor : ExpressionVisitor
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string MemberExpString;
 | 
				
			||||||
 | 
					            public bool Result { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public static bool IsExists(Expression selector, Expression memberExp)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var visitor = new TestMemberExpressionVisitor { MemberExpString = memberExp.ToString() };
 | 
				
			||||||
 | 
					                visitor.Visit(selector);
 | 
				
			||||||
 | 
					                return visitor.Result;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            protected override Expression VisitMember(MemberExpression node)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (!Result && node.ToString() == MemberExpString) Result = true;
 | 
				
			||||||
 | 
					                return node;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								Examples/orm_vs/Properties/launchSettings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Examples/orm_vs/Properties/launchSettings.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "profiles": {
 | 
				
			||||||
 | 
					    "WSL": {
 | 
				
			||||||
 | 
					      "commandName": "WSL2",
 | 
				
			||||||
 | 
					      "distributionName": ""
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,95 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.Text;
 | 
					 | 
				
			||||||
using System.Linq.Expressions;
 | 
					 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
using System.Reflection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace FreeSql.Extensions.Linq
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public static class ExprHelper
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public static object GetConstExprValue(this Expression exp)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (exp.IsParameter()) return null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var expStack = new Stack<Expression>();
 | 
					 | 
				
			||||||
            var exp2 = exp;
 | 
					 | 
				
			||||||
            while (true)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                switch (exp2?.NodeType)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    case ExpressionType.Constant:
 | 
					 | 
				
			||||||
                        expStack.Push(exp2);
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    case ExpressionType.MemberAccess:
 | 
					 | 
				
			||||||
                        expStack.Push(exp2);
 | 
					 | 
				
			||||||
                        exp2 = (exp2 as MemberExpression).Expression;
 | 
					 | 
				
			||||||
                        if (exp2 == null) break;
 | 
					 | 
				
			||||||
                        continue;
 | 
					 | 
				
			||||||
                    case ExpressionType.Call:
 | 
					 | 
				
			||||||
                        return Expression.Lambda(exp).Compile().DynamicInvoke();
 | 
					 | 
				
			||||||
                    case ExpressionType.TypeAs:
 | 
					 | 
				
			||||||
                    case ExpressionType.Convert:
 | 
					 | 
				
			||||||
                        var oper2 = (exp2 as UnaryExpression).Operand;
 | 
					 | 
				
			||||||
                        if (oper2.NodeType == ExpressionType.Parameter)
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            var oper2Parm = oper2 as ParameterExpression;
 | 
					 | 
				
			||||||
                            expStack.Push(exp2.Type.IsAbstract || exp2.Type.IsInterface ? oper2Parm : Expression.Parameter(exp2.Type, oper2Parm.Name));
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        else
 | 
					 | 
				
			||||||
                            expStack.Push(oper2);
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            object firstValue = null;
 | 
					 | 
				
			||||||
            switch (expStack.First().NodeType)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                case ExpressionType.Constant:
 | 
					 | 
				
			||||||
                    var expStackFirst = expStack.Pop() as ConstantExpression;
 | 
					 | 
				
			||||||
                    firstValue = expStackFirst?.Value;
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                case ExpressionType.MemberAccess:
 | 
					 | 
				
			||||||
                    var expStackFirstMem = expStack.First() as MemberExpression;
 | 
					 | 
				
			||||||
                    if (expStackFirstMem.Expression?.NodeType == ExpressionType.Constant)
 | 
					 | 
				
			||||||
                        firstValue = (expStackFirstMem.Expression as ConstantExpression)?.Value;
 | 
					 | 
				
			||||||
                    else
 | 
					 | 
				
			||||||
                        return Expression.Lambda(exp).Compile().DynamicInvoke();
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            while (expStack.Any())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                var expStackItem = expStack.Pop();
 | 
					 | 
				
			||||||
                switch (expStackItem.NodeType)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    case ExpressionType.MemberAccess:
 | 
					 | 
				
			||||||
                        var memExp = expStackItem as MemberExpression;
 | 
					 | 
				
			||||||
                        if (memExp.Member.MemberType == MemberTypes.Property)
 | 
					 | 
				
			||||||
                            firstValue = ((PropertyInfo)memExp.Member).GetValue(firstValue, null);
 | 
					 | 
				
			||||||
                        else if (memExp.Member.MemberType == MemberTypes.Field)
 | 
					 | 
				
			||||||
                            firstValue = ((FieldInfo)memExp.Member).GetValue(firstValue);
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return firstValue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static bool IsParameter(this Expression exp)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var test = new TestParameterExpressionVisitor();
 | 
					 | 
				
			||||||
            test.Visit(exp);
 | 
					 | 
				
			||||||
            return test.Result;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        internal class TestParameterExpressionVisitor : ExpressionVisitor
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            public bool Result { get; private set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            protected override Expression VisitParameter(ParameterExpression node)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (!Result) Result = true;
 | 
					 | 
				
			||||||
                return node;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using Newtonsoft.Json;
 | 
					using Newtonsoft.Json;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
@@ -91,35 +91,166 @@ namespace FreeSql.Tests.MySqlConnector
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void AsSelect()
 | 
					        public void AsSelect()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.mysql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToOne、ManyToOne
 | 
					            //OneToOne、ManyToOne
 | 
				
			||||||
            var t0 = g.mysql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
					            var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
					FROM `Tag` a 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` 
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
            //WHERE (a__Parent__Parent.`Name` = '粤语')
 | 
					LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (a__Parent__Parent.`Name` = '粤语')", t0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToMany
 | 
					            //OneToMany
 | 
				
			||||||
            var t1 = g.mysql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
					            var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
				
			||||||
            //WHERE (exists(SELECT 1 
 | 
					FROM `Tag` a 
 | 
				
			||||||
            //    FROM `Tag` t 
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
					    FROM `Tag` t 
 | 
				
			||||||
            //    WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) 
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
            //    limit 0,1))
 | 
					    WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) 
 | 
				
			||||||
 | 
					    limit 0,1))", t1);
 | 
				
			||||||
 | 
					            var t11 = fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a.`Id`) AND (t__Parent.`Id` = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t11);
 | 
				
			||||||
 | 
					            var t12 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a__Parent.`Id`) AND (t__Parent.`Id` = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t12);
 | 
				
			||||||
 | 
					            var t13 = fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a.`Id`) AND (t__Parent.`Id` = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t13);
 | 
				
			||||||
 | 
					            var t14 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a__Parent.`Id`) AND (t__Parent.`Id` = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t14);
 | 
				
			||||||
 | 
					            var t15 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (((a.`Name`) in (SELECT t.`Name` as1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a__Parent.`Id`) AND (t__Parent.`Id` = 10))))", t15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //ManyToMany
 | 
					            //ManyToMany
 | 
				
			||||||
            var t2 = g.mysql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
					            var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
					            fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).First();
 | 
				
			||||||
            //FROM `Song` a
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
				
			||||||
            //WHERE(exists(SELECT 1
 | 
					FROM `Song` a 
 | 
				
			||||||
            //    FROM `Song_tag` Mt_Ms
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1
 | 
					    FROM `Song_tag` Mt_Ms 
 | 
				
			||||||
            //        FROM `Tag` t
 | 
					    WHERE (Mt_Ms.`Song_id` = a.`Id`) AND (exists(SELECT 1 
 | 
				
			||||||
            //        WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`)
 | 
					        FROM `Tag` t 
 | 
				
			||||||
            //        limit 0, 1))
 | 
					        WHERE (t.`Name` = '国语') AND (t.`Id` = Mt_Ms.`Tag_id`) 
 | 
				
			||||||
            //    limit 0, 1))
 | 
					        limit 0,1)) 
 | 
				
			||||||
 | 
					    limit 0,1))", t2);
 | 
				
			||||||
 | 
					            var t21 = fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
				
			||||||
 | 
					FROM `Song` a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.`Tag_id` = t.`Id`) AND (Mt_Ma.`Song_id` = a.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (t.`Name` = '国语') 
 | 
				
			||||||
 | 
					    limit 0,1))", t21);
 | 
				
			||||||
 | 
					            var t22 = fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
				
			||||||
 | 
					FROM `Song` a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.`Tag_id` = t.`Id`) AND (Mt_Ma.`Song_id` = a.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (t.`Name` = '国语') 
 | 
				
			||||||
 | 
					    limit 0,1))", t22);
 | 
				
			||||||
 | 
					            var t23 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Song` s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.`Song_id` = s.`Id`) AND (Ms_Ma__Parent.`Tag_id` = a__Parent.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (s.`Title` = '中国人') 
 | 
				
			||||||
 | 
					    limit 0,1))", t23);
 | 
				
			||||||
 | 
					            var t24 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Song` s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.`Song_id` = s.`Id`) AND (Ms_Ma__Parent.`Tag_id` = a__Parent.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (s.`Title` = '中国人') 
 | 
				
			||||||
 | 
					    limit 0,1))", t24);
 | 
				
			||||||
 | 
					            var t25 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (((a.`Name`) in (SELECT s.`Title` as1 
 | 
				
			||||||
 | 
					    FROM `Song` s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.`Song_id` = s.`Id`) AND (Ms_Ma__Parent.`Tag_id` = a__Parent.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (s.`Title` = '中国人'))))", t25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var t3 = fsql.Select<Song>().ToList(r => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                r.Title,
 | 
				
			||||||
 | 
					                c2 = r.Tags.Count,
 | 
				
			||||||
 | 
					                c3 = r.Tags.Count(),
 | 
				
			||||||
 | 
					                c4 = r.Tags.Count(tag => tag.Id > 0),
 | 
				
			||||||
 | 
					                s1 = r.Tags.Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                a1 = r.Tags.Average(b => b.Id + 1),
 | 
				
			||||||
 | 
					                m1 = r.Tags.Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                m2 = r.Tags.Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                f1 = r.Tags.Select(b => b.Name).First(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                count = r.Tags.AsSelect().Count(),
 | 
				
			||||||
 | 
					                sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
				
			||||||
 | 
					                max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                first = r.Tags.AsSelect().First(b => b.Name)
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -83,35 +83,150 @@ namespace FreeSql.Tests.Dameng
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void AsSelect()
 | 
					        public void AsSelect()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.dameng;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToOne、ManyToOne
 | 
					            //OneToOne、ManyToOne
 | 
				
			||||||
            var t0 = g.dameng.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
					            var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` 
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
            //WHERE (a__Parent__Parent.`Name` = '粤语')
 | 
					LEFT JOIN ""TAG"" a__Parent__Parent ON a__Parent__Parent.""ID"" = a__Parent.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (a__Parent__Parent.""NAME"" = '粤语')", t0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToMany
 | 
					            //OneToMany
 | 
				
			||||||
            var t1 = g.dameng.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
					            var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a.""DDD"", a.""NAME"" 
 | 
				
			||||||
            //WHERE (exists(SELECT 1 
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
            //    FROM `Tag` t 
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
            //    WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) 
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
            //    limit 0,1))
 | 
					    WHERE (t__Parent.""ID"" = 10) AND (t.""PARENT_ID"" = a.""ID"")))", t1);
 | 
				
			||||||
 | 
					            var t11 = fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a.""DDD"", a.""NAME"" 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a.""ID"") AND (t__Parent.""ID"" = 10)))", t11);
 | 
				
			||||||
 | 
					            var t12 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a__Parent.""ID"") AND (t__Parent.""ID"" = 10)))", t12);
 | 
				
			||||||
 | 
					            var t13 = fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a.""DDD"", a.""NAME"" 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a.""ID"") AND (t__Parent.""ID"" = 10)))", t13);
 | 
				
			||||||
 | 
					            var t14 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a__Parent.""ID"") AND (t__Parent.""ID"" = 10)))", t14);
 | 
				
			||||||
 | 
					            var t15 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (((a.""NAME"") in (SELECT t.""NAME"" as1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a__Parent.""ID"") AND (t__Parent.""ID"" = 10))))", t15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //ManyToMany
 | 
					            //ManyToMany
 | 
				
			||||||
            var t2 = g.dameng.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
					            var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
					            fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).First();
 | 
				
			||||||
            //FROM `Song` a
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""CREATE_TIME"", a.""IS_DELETED"", a.""TITLE"", a.""URL"" 
 | 
				
			||||||
            //WHERE(exists(SELECT 1
 | 
					FROM ""SONG"" a 
 | 
				
			||||||
            //    FROM `Song_tag` Mt_Ms
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1
 | 
					    FROM ""SONG_TAG"" Mt_Ms 
 | 
				
			||||||
            //        FROM `Tag` t
 | 
					    WHERE (Mt_Ms.""SONG_ID"" = a.""ID"") AND (exists(SELECT 1 
 | 
				
			||||||
            //        WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`)
 | 
					        FROM ""TAG"" t 
 | 
				
			||||||
            //        limit 0, 1))
 | 
					        WHERE (t.""NAME"" = '国语') AND (t.""ID"" = Mt_Ms.""TAG_ID"")))))", t2);
 | 
				
			||||||
            //    limit 0, 1))
 | 
					            var t21 = fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""CREATE_TIME"", a.""IS_DELETED"", a.""TITLE"", a.""URL"" 
 | 
				
			||||||
 | 
					FROM ""SONG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""TAG_ID"" = t.""ID"") AND (Mt_Ma.""SONG_ID"" = a.""ID""))) AND (t.""NAME"" = '国语')))", t21);
 | 
				
			||||||
 | 
					            var t22 = fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""CREATE_TIME"", a.""IS_DELETED"", a.""TITLE"", a.""URL"" 
 | 
				
			||||||
 | 
					FROM ""SONG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""TAG_ID"" = t.""ID"") AND (Mt_Ma.""SONG_ID"" = a.""ID""))) AND (t.""NAME"" = '国语')))", t22);
 | 
				
			||||||
 | 
					            var t23 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""SONG"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""SONG_ID"" = s.""ID"") AND (Ms_Ma__Parent.""TAG_ID"" = a__Parent.""ID""))) AND (s.""TITLE"" = '中国人')))", t23);
 | 
				
			||||||
 | 
					            var t24 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""SONG"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""SONG_ID"" = s.""ID"") AND (Ms_Ma__Parent.""TAG_ID"" = a__Parent.""ID""))) AND (s.""TITLE"" = '中国人')))", t24);
 | 
				
			||||||
 | 
					            var t25 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (((a.""NAME"") in (SELECT s.""TITLE"" as1 
 | 
				
			||||||
 | 
					    FROM ""SONG"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""SONG_ID"" = s.""ID"") AND (Ms_Ma__Parent.""TAG_ID"" = a__Parent.""ID""))) AND (s.""TITLE"" = '中国人'))))", t25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var t3 = fsql.Select<Song>().ToList(r => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                r.Title,
 | 
				
			||||||
 | 
					                c2 = r.Tags.Count,
 | 
				
			||||||
 | 
					                c3 = r.Tags.Count(),
 | 
				
			||||||
 | 
					                c4 = r.Tags.Count(tag => tag.Id > 0),
 | 
				
			||||||
 | 
					                s1 = r.Tags.Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                a1 = r.Tags.Average(b => b.Id + 1),
 | 
				
			||||||
 | 
					                m1 = r.Tags.Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                m2 = r.Tags.Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                f1 = r.Tags.Select(b => b.Name).First(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                count = r.Tags.AsSelect().Count(),
 | 
				
			||||||
 | 
					                sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
				
			||||||
 | 
					                max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                first = r.Tags.AsSelect().First(b => b.Name)
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -83,35 +83,150 @@ namespace FreeSql.Tests.Firebird
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void AsSelect()
 | 
					        public void AsSelect()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.firebird;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToOne、ManyToOne
 | 
					            //OneToOne、ManyToOne
 | 
				
			||||||
            var t0 = g.firebird.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
					            var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` 
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
            //WHERE (a__Parent__Parent.`Name` = '粤语')
 | 
					LEFT JOIN ""TAG"" a__Parent__Parent ON a__Parent__Parent.""ID"" = a__Parent.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (a__Parent__Parent.""NAME"" = '粤语')", t0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToMany
 | 
					            //OneToMany
 | 
				
			||||||
            var t1 = g.firebird.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
					            var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a.""DDD"", a.""NAME"" 
 | 
				
			||||||
            //WHERE (exists(SELECT 1 
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
            //	FROM `Tag` t 
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
            //	LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
            //	WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) 
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
            //	limit 0,1))
 | 
					    WHERE (t__Parent.""ID"" = 10) AND (t.""PARENT_ID"" = a.""ID"")))", t1);
 | 
				
			||||||
 | 
					            var t11 = fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a.""DDD"", a.""NAME"" 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a.""ID"") AND (t__Parent.""ID"" = 10)))", t11);
 | 
				
			||||||
 | 
					            var t12 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a__Parent.""ID"") AND (t__Parent.""ID"" = 10)))", t12);
 | 
				
			||||||
 | 
					            var t13 = fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a.""DDD"", a.""NAME"" 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a.""ID"") AND (t__Parent.""ID"" = 10)))", t13);
 | 
				
			||||||
 | 
					            var t14 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a__Parent.""ID"") AND (t__Parent.""ID"" = 10)))", t14);
 | 
				
			||||||
 | 
					            var t15 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (((a.""NAME"") in (SELECT t.""NAME"" as1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a__Parent.""ID"") AND (t__Parent.""ID"" = 10))))", t15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //ManyToMany
 | 
					            //ManyToMany
 | 
				
			||||||
            var t2 = g.firebird.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
					            var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
					            fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).First();
 | 
				
			||||||
            //FROM `Song` a
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""CREATE_TIME"", a.""IS_DELETED"", a.""TITLE"", a.""URL"" 
 | 
				
			||||||
            //WHERE(exists(SELECT 1
 | 
					FROM ""SONG"" a 
 | 
				
			||||||
            //	FROM `Song_tag` Mt_Ms
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
            //	WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1
 | 
					    FROM ""SONG_TAG"" Mt_Ms 
 | 
				
			||||||
            //		FROM `Tag` t
 | 
					    WHERE (Mt_Ms.""SONG_ID"" = a.""ID"") AND (exists(SELECT FIRST 1 1 
 | 
				
			||||||
            //		WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`)
 | 
					        FROM ""TAG"" t 
 | 
				
			||||||
            //		limit 0, 1))
 | 
					        WHERE (t.""NAME"" = '国语') AND (t.""ID"" = Mt_Ms.""TAG_ID"")))))", t2);
 | 
				
			||||||
            //	limit 0, 1))
 | 
					            var t21 = fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""CREATE_TIME"", a.""IS_DELETED"", a.""TITLE"", a.""URL"" 
 | 
				
			||||||
 | 
					FROM ""SONG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""TAG_ID"" = t.""ID"") AND (Mt_Ma.""SONG_ID"" = a.""ID""))) AND (t.""NAME"" = '国语')))", t21);
 | 
				
			||||||
 | 
					            var t22 = fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""CREATE_TIME"", a.""IS_DELETED"", a.""TITLE"", a.""URL"" 
 | 
				
			||||||
 | 
					FROM ""SONG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""TAG_ID"" = t.""ID"") AND (Mt_Ma.""SONG_ID"" = a.""ID""))) AND (t.""NAME"" = '国语')))", t22);
 | 
				
			||||||
 | 
					            var t23 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					    FROM ""SONG"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""SONG_ID"" = s.""ID"") AND (Ms_Ma__Parent.""TAG_ID"" = a__Parent.""ID""))) AND (s.""TITLE"" = '中国人')))", t23);
 | 
				
			||||||
 | 
					            var t24 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					    FROM ""SONG"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""SONG_ID"" = s.""ID"") AND (Ms_Ma__Parent.""TAG_ID"" = a__Parent.""ID""))) AND (s.""TITLE"" = '中国人')))", t24);
 | 
				
			||||||
 | 
					            var t25 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (((a.""NAME"") in (SELECT s.""TITLE"" as1 
 | 
				
			||||||
 | 
					    FROM ""SONG"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT FIRST 1 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""SONG_ID"" = s.""ID"") AND (Ms_Ma__Parent.""TAG_ID"" = a__Parent.""ID""))) AND (s.""TITLE"" = '中国人'))))", t25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var t3 = fsql.Select<Song>().ToList(r => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                r.Title,
 | 
				
			||||||
 | 
					                c2 = r.Tags.Count,
 | 
				
			||||||
 | 
					                c3 = r.Tags.Count(),
 | 
				
			||||||
 | 
					                c4 = r.Tags.Count(tag => tag.Id > 0),
 | 
				
			||||||
 | 
					                s1 = r.Tags.Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                a1 = r.Tags.Average(b => b.Id + 1),
 | 
				
			||||||
 | 
					                m1 = r.Tags.Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                m2 = r.Tags.Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                f1 = r.Tags.Select(b => b.Name).First(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                count = r.Tags.AsSelect().Count(),
 | 
				
			||||||
 | 
					                sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
				
			||||||
 | 
					                max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                first = r.Tags.AsSelect().First(b => b.Name)
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,16 +26,16 @@ namespace FreeSql.Tests.Linq
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void GetConstExprValue()
 | 
					        public void GetConstExprValue()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Assert.Equal(-1, ExprHelper.GetConstExprValue(Expression.Constant(-1)));
 | 
					            Assert.Equal(-1, Expression.Constant(-1).GetConstExprValue());
 | 
				
			||||||
            Assert.Equal(-2, ExprHelper.GetConstExprValue(Expression.Constant(-2)));
 | 
					            Assert.Equal(-2, Expression.Constant(-2).GetConstExprValue());
 | 
				
			||||||
            Assert.Equal(0, ExprHelper.GetConstExprValue(Expression.Constant(0)));
 | 
					            Assert.Equal(0, Expression.Constant(0).GetConstExprValue());
 | 
				
			||||||
            Assert.Equal(1, ExprHelper.GetConstExprValue(Expression.Constant(1)));
 | 
					            Assert.Equal(1, Expression.Constant(1).GetConstExprValue());
 | 
				
			||||||
            Assert.Equal(2, ExprHelper.GetConstExprValue(Expression.Constant(2)));
 | 
					            Assert.Equal(2, Expression.Constant(2).GetConstExprValue());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var arr = new[] { -1, -2, 0, 1, 2 };
 | 
					            var arr = new[] { -1, -2, 0, 1, 2 };
 | 
				
			||||||
            for (var a = 0; a < arr.Length; a++)
 | 
					            for (var a = 0; a < arr.Length; a++)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Assert.Equal(arr[a], ExprHelper.GetConstExprValue(Expression.Constant(arr[a])));
 | 
					                Assert.Equal(arr[a], Expression.Constant(arr[a]).GetConstExprValue());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var arritems = new[]
 | 
					            var arritems = new[]
 | 
				
			||||||
@@ -48,8 +48,8 @@ namespace FreeSql.Tests.Linq
 | 
				
			|||||||
            }; 
 | 
					            }; 
 | 
				
			||||||
            for (var a = 0; a < arr.Length; a++)
 | 
					            for (var a = 0; a < arr.Length; a++)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Assert.Equal(arritems[a].Prop, ExprHelper.GetConstExprValue(Expression.Constant(arritems[a].Prop)));
 | 
					                Assert.Equal(arritems[a].Prop, Expression.Constant(arritems[a].Prop).GetConstExprValue());
 | 
				
			||||||
                Assert.Equal(arritems[a].Field, ExprHelper.GetConstExprValue(Expression.Constant(arritems[a].Field)));
 | 
					                Assert.Equal(arritems[a].Field, Expression.Constant(arritems[a].Field).GetConstExprValue());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -72,35 +72,150 @@ namespace FreeSql.Tests.MsAccess
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void AsSelect()
 | 
					        public void AsSelect()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.msaccess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToOne、ManyToOne
 | 
					            //OneToOne、ManyToOne
 | 
				
			||||||
            var t0 = g.msaccess.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
					            var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
				
			||||||
            //SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").First();
 | 
				
			||||||
            //FROM [Tag] a 
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as as3, a__Parent.[Parent_id] as as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as as7, a.[Name] as as8 
 | 
				
			||||||
            //LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] 
 | 
					FROM ([Tag] a 
 | 
				
			||||||
            //LEFT JOIN [Tag] a__Parent__Parent ON a__Parent__Parent.[Id] = a__Parent.[Parent_id] 
 | 
					LEFT JOIN [Tag] a__Parent ON (a__Parent.[Id] = a.[Parent_id]))  
 | 
				
			||||||
            //WHERE (a__Parent__Parent.[Name] = '粤语')
 | 
					LEFT JOIN [Tag] a__Parent__Parent ON (a__Parent__Parent.[Id] = a__Parent.[Parent_id]) 
 | 
				
			||||||
 | 
					WHERE (a__Parent__Parent.[Name] = '粤语')", t0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToMany
 | 
					            //OneToMany
 | 
				
			||||||
            var t1 = g.msaccess.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
					            var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
            //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] 
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
            //FROM [Tag] a 
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] 
 | 
				
			||||||
            //WHERE (exists(SELECT 1 
 | 
					FROM [Tag] a 
 | 
				
			||||||
            //    FROM [Tag] t 
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
            //    LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] 
 | 
					    FROM [Tag] t 
 | 
				
			||||||
            //    WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) 
 | 
					    LEFT JOIN [Tag] t__Parent ON (t__Parent.[Id] = t.[Parent_id]) 
 | 
				
			||||||
            //    limit 0,1))
 | 
					    WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id])))", t1);
 | 
				
			||||||
 | 
					            var t11 = fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON (t__Parent.[Id] = t.[Parent_id]) 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a.[Id]) AND (t__Parent.[Id] = 10)))", t11);
 | 
				
			||||||
 | 
					            var t12 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as as3, a__Parent.[Parent_id] as as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as as7, a.[Name] as as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON (a__Parent.[Id] = a.[Parent_id]) 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON (t__Parent.[Id] = t.[Parent_id]) 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a__Parent.[Id]) AND (t__Parent.[Id] = 10)))", t12);
 | 
				
			||||||
 | 
					            var t13 = fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON (t__Parent.[Id] = t.[Parent_id]) 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a.[Id]) AND (t__Parent.[Id] = 10)))", t13);
 | 
				
			||||||
 | 
					            var t14 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as as3, a__Parent.[Parent_id] as as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as as7, a.[Name] as as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON (a__Parent.[Id] = a.[Parent_id]) 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON (t__Parent.[Id] = t.[Parent_id]) 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a__Parent.[Id]) AND (t__Parent.[Id] = 10)))", t14);
 | 
				
			||||||
 | 
					            var t15 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as as3, a__Parent.[Parent_id] as as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as as7, a.[Name] as as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON (a__Parent.[Id] = a.[Parent_id]) 
 | 
				
			||||||
 | 
					WHERE (((a.[Name]) in (SELECT t.[Name] as as1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON (t__Parent.[Id] = t.[Parent_id]) 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a__Parent.[Id]) AND (t__Parent.[Id] = 10))))", t15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //ManyToMany
 | 
					            //ManyToMany
 | 
				
			||||||
            var t2 = g.msaccess.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
					            var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
            //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] 
 | 
					            fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).First();
 | 
				
			||||||
            //FROM [Song] a
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] 
 | 
				
			||||||
            //WHERE(exists(SELECT 1
 | 
					FROM [Song] a 
 | 
				
			||||||
            //    FROM [Song_tag] Mt_Ms
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
            //    WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1
 | 
					    FROM [Song_tag] Mt_Ms 
 | 
				
			||||||
            //        FROM [Tag] t
 | 
					    WHERE (Mt_Ms.[Song_id] = a.[Id]) AND (exists(SELECT TOP 1 1 
 | 
				
			||||||
            //        WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id])
 | 
					        FROM [Tag] t 
 | 
				
			||||||
            //        limit 0, 1))
 | 
					        WHERE (t.[Name] = '国语') AND (t.[Id] = Mt_Ms.[Tag_id])))))", t2);
 | 
				
			||||||
            //    limit 0, 1))
 | 
					            var t21 = fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] 
 | 
				
			||||||
 | 
					FROM [Song] a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.[Tag_id] = t.[Id]) AND (Mt_Ma.[Song_id] = a.[Id]))) AND (t.[Name] = '国语')))", t21);
 | 
				
			||||||
 | 
					            var t22 = fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] 
 | 
				
			||||||
 | 
					FROM [Song] a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.[Tag_id] = t.[Id]) AND (Mt_Ma.[Song_id] = a.[Id]))) AND (t.[Name] = '国语')))", t22);
 | 
				
			||||||
 | 
					            var t23 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as as3, a__Parent.[Parent_id] as as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as as7, a.[Name] as as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON (a__Parent.[Id] = a.[Parent_id]) 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Song] s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.[Song_id] = s.[Id]) AND (Ms_Ma__Parent.[Tag_id] = a__Parent.[Id]))) AND (s.[Title] = '中国人')))", t23);
 | 
				
			||||||
 | 
					            var t24 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as as3, a__Parent.[Parent_id] as as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as as7, a.[Name] as as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON (a__Parent.[Id] = a.[Parent_id]) 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Song] s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.[Song_id] = s.[Id]) AND (Ms_Ma__Parent.[Tag_id] = a__Parent.[Id]))) AND (s.[Title] = '中国人')))", t24);
 | 
				
			||||||
 | 
					            var t25 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as as3, a__Parent.[Parent_id] as as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as as7, a.[Name] as as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON (a__Parent.[Id] = a.[Parent_id]) 
 | 
				
			||||||
 | 
					WHERE (((a.[Name]) in (SELECT s.[Title] as as1 
 | 
				
			||||||
 | 
					    FROM [Song] s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.[Song_id] = s.[Id]) AND (Ms_Ma__Parent.[Tag_id] = a__Parent.[Id]))) AND (s.[Title] = '中国人'))))", t25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var t3 = fsql.Select<Song>().First(r => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                r.Title,
 | 
				
			||||||
 | 
					                c2 = r.Tags.Count,
 | 
				
			||||||
 | 
					                c3 = r.Tags.Count(),
 | 
				
			||||||
 | 
					                c4 = r.Tags.Count(tag => tag.Id > 0),
 | 
				
			||||||
 | 
					                s1 = r.Tags.Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                a1 = r.Tags.Average(b => b.Id + 1),
 | 
				
			||||||
 | 
					                m1 = r.Tags.Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                m2 = r.Tags.Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                f1 = r.Tags.Select(b => b.Name).First(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                count = r.Tags.AsSelect().Count(),
 | 
				
			||||||
 | 
					                sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
				
			||||||
 | 
					                max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                first = r.Tags.AsSelect().First(b => b.Name)
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using FreeSql.Internal.CommonProvider;
 | 
					using FreeSql.Internal.CommonProvider;
 | 
				
			||||||
using Newtonsoft.Json;
 | 
					using Newtonsoft.Json;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
@@ -93,35 +93,166 @@ namespace FreeSql.Tests.MySql
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void AsSelect()
 | 
					        public void AsSelect()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.mysql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToOne、ManyToOne
 | 
					            //OneToOne、ManyToOne
 | 
				
			||||||
            var t0 = g.mysql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
					            var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
					FROM `Tag` a 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` 
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
            //WHERE (a__Parent__Parent.`Name` = '粤语')
 | 
					LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (a__Parent__Parent.`Name` = '粤语')", t0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToMany
 | 
					            //OneToMany
 | 
				
			||||||
            var t1 = g.mysql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
					            var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
				
			||||||
            //WHERE (exists(SELECT 1 
 | 
					FROM `Tag` a 
 | 
				
			||||||
            //    FROM `Tag` t 
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
					    FROM `Tag` t 
 | 
				
			||||||
            //    WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) 
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
            //    limit 0,1))
 | 
					    WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) 
 | 
				
			||||||
 | 
					    limit 0,1))", t1);
 | 
				
			||||||
 | 
					            var t11 = fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a.`Id`) AND (t__Parent.`Id` = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t11);
 | 
				
			||||||
 | 
					            var t12 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a__Parent.`Id`) AND (t__Parent.`Id` = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t12);
 | 
				
			||||||
 | 
					            var t13 = fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a.`Id`) AND (t__Parent.`Id` = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t13);
 | 
				
			||||||
 | 
					            var t14 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a__Parent.`Id`) AND (t__Parent.`Id` = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t14);
 | 
				
			||||||
 | 
					            var t15 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (((a.`Name`) in (SELECT t.`Name` as1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
				
			||||||
 | 
					    WHERE (t.`Parent_id` = a__Parent.`Id`) AND (t__Parent.`Id` = 10))))", t15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //ManyToMany
 | 
					            //ManyToMany
 | 
				
			||||||
            var t2 = g.mysql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
					            var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
					            fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).First();
 | 
				
			||||||
            //FROM `Song` a
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
				
			||||||
            //WHERE(exists(SELECT 1
 | 
					FROM `Song` a 
 | 
				
			||||||
            //    FROM `Song_tag` Mt_Ms
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1
 | 
					    FROM `Song_tag` Mt_Ms 
 | 
				
			||||||
            //        FROM `Tag` t
 | 
					    WHERE (Mt_Ms.`Song_id` = a.`Id`) AND (exists(SELECT 1 
 | 
				
			||||||
            //        WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`)
 | 
					        FROM `Tag` t 
 | 
				
			||||||
            //        limit 0, 1))
 | 
					        WHERE (t.`Name` = '国语') AND (t.`Id` = Mt_Ms.`Tag_id`) 
 | 
				
			||||||
            //    limit 0, 1))
 | 
					        limit 0,1)) 
 | 
				
			||||||
 | 
					    limit 0,1))", t2);
 | 
				
			||||||
 | 
					            var t21 = fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
				
			||||||
 | 
					FROM `Song` a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.`Tag_id` = t.`Id`) AND (Mt_Ma.`Song_id` = a.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (t.`Name` = '国语') 
 | 
				
			||||||
 | 
					    limit 0,1))", t21);
 | 
				
			||||||
 | 
					            var t22 = fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
				
			||||||
 | 
					FROM `Song` a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Tag` t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.`Tag_id` = t.`Id`) AND (Mt_Ma.`Song_id` = a.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (t.`Name` = '国语') 
 | 
				
			||||||
 | 
					    limit 0,1))", t22);
 | 
				
			||||||
 | 
					            var t23 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Song` s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.`Song_id` = s.`Id`) AND (Ms_Ma__Parent.`Tag_id` = a__Parent.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (s.`Title` = '中国人') 
 | 
				
			||||||
 | 
					    limit 0,1))", t23);
 | 
				
			||||||
 | 
					            var t24 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM `Song` s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.`Song_id` = s.`Id`) AND (Ms_Ma__Parent.`Tag_id` = a__Parent.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (s.`Title` = '中国人') 
 | 
				
			||||||
 | 
					    limit 0,1))", t24);
 | 
				
			||||||
 | 
					            var t25 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
				
			||||||
 | 
					FROM `Tag` a 
 | 
				
			||||||
 | 
					LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
				
			||||||
 | 
					WHERE (((a.`Name`) in (SELECT s.`Title` as1 
 | 
				
			||||||
 | 
					    FROM `Song` s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM `Song_tag` Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.`Song_id` = s.`Id`) AND (Ms_Ma__Parent.`Tag_id` = a__Parent.`Id`) 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (s.`Title` = '中国人'))))", t25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var t3 = fsql.Select<Song>().ToList(r => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                r.Title,
 | 
				
			||||||
 | 
					                c2 = r.Tags.Count,
 | 
				
			||||||
 | 
					                c3 = r.Tags.Count(),
 | 
				
			||||||
 | 
					                c4 = r.Tags.Count(tag => tag.Id > 0),
 | 
				
			||||||
 | 
					                s1 = r.Tags.Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                a1 = r.Tags.Average(b => b.Id + 1),
 | 
				
			||||||
 | 
					                m1 = r.Tags.Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                m2 = r.Tags.Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                f1 = r.Tags.Select(b => b.Name).First(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                count = r.Tags.AsSelect().Count(),
 | 
				
			||||||
 | 
					                sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
				
			||||||
 | 
					                max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                first = r.Tags.AsSelect().First(b => b.Name)
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -83,35 +83,150 @@ namespace FreeSql.Tests.Oracle
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void AsSelect()
 | 
					        public void AsSelect()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.oracle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToOne、ManyToOne
 | 
					            //OneToOne、ManyToOne
 | 
				
			||||||
            var t0 = g.oracle.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
					            var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` 
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
            //WHERE (a__Parent__Parent.`Name` = '粤语')
 | 
					LEFT JOIN ""TAG"" a__Parent__Parent ON a__Parent__Parent.""ID"" = a__Parent.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (a__Parent__Parent.""NAME"" = '粤语')", t0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToMany
 | 
					            //OneToMany
 | 
				
			||||||
            var t1 = g.oracle.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
					            var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a.""DDD"", a.""NAME"" 
 | 
				
			||||||
            //WHERE (exists(SELECT 1 
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
            //    FROM `Tag` t 
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
            //    WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) 
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
            //    limit 0,1))
 | 
					    WHERE (t__Parent.""ID"" = 10) AND (t.""PARENT_ID"" = a.""ID"")))", t1);
 | 
				
			||||||
 | 
					            var t11 = fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a.""DDD"", a.""NAME"" 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a.""ID"") AND (t__Parent.""ID"" = 10)))", t11);
 | 
				
			||||||
 | 
					            var t12 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a__Parent.""ID"") AND (t__Parent.""ID"" = 10)))", t12);
 | 
				
			||||||
 | 
					            var t13 = fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a.""DDD"", a.""NAME"" 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a.""ID"") AND (t__Parent.""ID"" = 10)))", t13);
 | 
				
			||||||
 | 
					            var t14 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a__Parent.""ID"") AND (t__Parent.""ID"" = 10)))", t14);
 | 
				
			||||||
 | 
					            var t15 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (((a.""NAME"") in (SELECT t.""NAME"" as1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""TAG"" t__Parent ON t__Parent.""ID"" = t.""PARENT_ID"" 
 | 
				
			||||||
 | 
					    WHERE (t.""PARENT_ID"" = a__Parent.""ID"") AND (t__Parent.""ID"" = 10))))", t15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //ManyToMany
 | 
					            //ManyToMany
 | 
				
			||||||
            var t2 = g.oracle.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
					            var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
					            fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).First();
 | 
				
			||||||
            //FROM `Song` a
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""CREATE_TIME"", a.""IS_DELETED"", a.""TITLE"", a.""URL"" 
 | 
				
			||||||
            //WHERE(exists(SELECT 1
 | 
					FROM ""SONG"" a 
 | 
				
			||||||
            //    FROM `Song_tag` Mt_Ms
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1
 | 
					    FROM ""SONG_TAG"" Mt_Ms 
 | 
				
			||||||
            //        FROM `Tag` t
 | 
					    WHERE (Mt_Ms.""SONG_ID"" = a.""ID"") AND (exists(SELECT 1 
 | 
				
			||||||
            //        WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`)
 | 
					        FROM ""TAG"" t 
 | 
				
			||||||
            //        limit 0, 1))
 | 
					        WHERE (t.""NAME"" = '国语') AND (t.""ID"" = Mt_Ms.""TAG_ID"")))))", t2);
 | 
				
			||||||
            //    limit 0, 1))
 | 
					            var t21 = fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""CREATE_TIME"", a.""IS_DELETED"", a.""TITLE"", a.""URL"" 
 | 
				
			||||||
 | 
					FROM ""SONG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""TAG_ID"" = t.""ID"") AND (Mt_Ma.""SONG_ID"" = a.""ID""))) AND (t.""NAME"" = '国语')))", t21);
 | 
				
			||||||
 | 
					            var t22 = fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""CREATE_TIME"", a.""IS_DELETED"", a.""TITLE"", a.""URL"" 
 | 
				
			||||||
 | 
					FROM ""SONG"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""TAG"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""TAG_ID"" = t.""ID"") AND (Mt_Ma.""SONG_ID"" = a.""ID""))) AND (t.""NAME"" = '国语')))", t22);
 | 
				
			||||||
 | 
					            var t23 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""SONG"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""SONG_ID"" = s.""ID"") AND (Ms_Ma__Parent.""TAG_ID"" = a__Parent.""ID""))) AND (s.""TITLE"" = '中国人')))", t23);
 | 
				
			||||||
 | 
					            var t24 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""SONG"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""SONG_ID"" = s.""ID"") AND (Ms_Ma__Parent.""TAG_ID"" = a__Parent.""ID""))) AND (s.""TITLE"" = '中国人')))", t24);
 | 
				
			||||||
 | 
					            var t25 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""ID"", a.""PARENT_ID"", a__Parent.""ID"" as3, a__Parent.""PARENT_ID"" as4, a__Parent.""DDD"", a__Parent.""NAME"", a.""DDD"" as7, a.""NAME"" as8 
 | 
				
			||||||
 | 
					FROM ""TAG"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""TAG"" a__Parent ON a__Parent.""ID"" = a.""PARENT_ID"" 
 | 
				
			||||||
 | 
					WHERE (((a.""NAME"") in (SELECT s.""TITLE"" as1 
 | 
				
			||||||
 | 
					    FROM ""SONG"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""SONG_TAG"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""SONG_ID"" = s.""ID"") AND (Ms_Ma__Parent.""TAG_ID"" = a__Parent.""ID""))) AND (s.""TITLE"" = '中国人'))))", t25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var t3 = fsql.Select<Song>().ToList(r => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                r.Title,
 | 
				
			||||||
 | 
					                c2 = r.Tags.Count,
 | 
				
			||||||
 | 
					                c3 = r.Tags.Count(),
 | 
				
			||||||
 | 
					                c4 = r.Tags.Count(tag => tag.Id > 0),
 | 
				
			||||||
 | 
					                s1 = r.Tags.Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                a1 = r.Tags.Average(b => b.Id + 1),
 | 
				
			||||||
 | 
					                m1 = r.Tags.Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                m2 = r.Tags.Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                f1 = r.Tags.Select(b => b.Name).First(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                count = r.Tags.AsSelect().Count(),
 | 
				
			||||||
 | 
					                sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
				
			||||||
 | 
					                max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                first = r.Tags.AsSelect().First(b => b.Name)
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -73,35 +73,166 @@ namespace FreeSql.Tests.PostgreSQL
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void AsSelect()
 | 
					        public void AsSelect()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.pgsql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToOne、ManyToOne
 | 
					            //OneToOne、ManyToOne
 | 
				
			||||||
            var t0 = g.pgsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
					            var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a__Parent.""id"" as3, a__Parent.""parent_id"" as4, a__Parent.""ddd"", a__Parent.""name"", a.""ddd"" as7, a.""name"" as8 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
					FROM ""tag"" a 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` 
 | 
					LEFT JOIN ""tag"" a__Parent ON a__Parent.""id"" = a.""parent_id"" 
 | 
				
			||||||
            //WHERE (a__Parent__Parent.`Name` = '粤语')
 | 
					LEFT JOIN ""tag"" a__Parent__Parent ON a__Parent__Parent.""id"" = a__Parent.""parent_id"" 
 | 
				
			||||||
 | 
					WHERE (a__Parent__Parent.""name"" = '粤语')", t0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToMany
 | 
					            //OneToMany
 | 
				
			||||||
            var t1 = g.pgsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
					            var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a.""ddd"", a.""name"" 
 | 
				
			||||||
            //WHERE (exists(SELECT 1 
 | 
					FROM ""tag"" a 
 | 
				
			||||||
            //    FROM `Tag` t 
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
					    FROM ""tag"" t 
 | 
				
			||||||
            //    WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) 
 | 
					    LEFT JOIN ""tag"" t__Parent ON t__Parent.""id"" = t.""parent_id"" 
 | 
				
			||||||
            //    limit 0,1))
 | 
					    WHERE (t__Parent.""id"" = 10) AND (t.""parent_id"" = a.""id"") 
 | 
				
			||||||
 | 
					    limit 1))", t1);
 | 
				
			||||||
 | 
					            var t11 = fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a.""ddd"", a.""name"" 
 | 
				
			||||||
 | 
					FROM ""tag"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""tag"" t__Parent ON t__Parent.""id"" = t.""parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""parent_id"" = a.""id"") AND (t__Parent.""id"" = 10) 
 | 
				
			||||||
 | 
					    limit 1))", t11);
 | 
				
			||||||
 | 
					            var t12 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a__Parent.""id"" as3, a__Parent.""parent_id"" as4, a__Parent.""ddd"", a__Parent.""name"", a.""ddd"" as7, a.""name"" as8 
 | 
				
			||||||
 | 
					FROM ""tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""tag"" a__Parent ON a__Parent.""id"" = a.""parent_id"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""tag"" t__Parent ON t__Parent.""id"" = t.""parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""parent_id"" = a__Parent.""id"") AND (t__Parent.""id"" = 10) 
 | 
				
			||||||
 | 
					    limit 1))", t12);
 | 
				
			||||||
 | 
					            var t13 = fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a.""ddd"", a.""name"" 
 | 
				
			||||||
 | 
					FROM ""tag"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""tag"" t__Parent ON t__Parent.""id"" = t.""parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""parent_id"" = a.""id"") AND (t__Parent.""id"" = 10) 
 | 
				
			||||||
 | 
					    limit 1))", t13);
 | 
				
			||||||
 | 
					            var t14 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a__Parent.""id"" as3, a__Parent.""parent_id"" as4, a__Parent.""ddd"", a__Parent.""name"", a.""ddd"" as7, a.""name"" as8 
 | 
				
			||||||
 | 
					FROM ""tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""tag"" a__Parent ON a__Parent.""id"" = a.""parent_id"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""tag"" t__Parent ON t__Parent.""id"" = t.""parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""parent_id"" = a__Parent.""id"") AND (t__Parent.""id"" = 10) 
 | 
				
			||||||
 | 
					    limit 1))", t14);
 | 
				
			||||||
 | 
					            var t15 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a__Parent.""id"" as3, a__Parent.""parent_id"" as4, a__Parent.""ddd"", a__Parent.""name"", a.""ddd"" as7, a.""name"" as8 
 | 
				
			||||||
 | 
					FROM ""tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""tag"" a__Parent ON a__Parent.""id"" = a.""parent_id"" 
 | 
				
			||||||
 | 
					WHERE (((a.""name"") in (SELECT t.""name"" as1 
 | 
				
			||||||
 | 
					    FROM ""tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""tag"" t__Parent ON t__Parent.""id"" = t.""parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""parent_id"" = a__Parent.""id"") AND (t__Parent.""id"" = 10))))", t15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //ManyToMany
 | 
					            //ManyToMany
 | 
				
			||||||
            var t2 = g.pgsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
					            var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
					            fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).First();
 | 
				
			||||||
            //FROM `Song` a
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""create_time"", a.""is_deleted"", a.""title"", a.""url"" 
 | 
				
			||||||
            //WHERE(exists(SELECT 1
 | 
					FROM ""song"" a 
 | 
				
			||||||
            //    FROM `Song_tag` Mt_Ms
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1
 | 
					    FROM ""song_tag"" Mt_Ms 
 | 
				
			||||||
            //        FROM `Tag` t
 | 
					    WHERE (Mt_Ms.""song_id"" = a.""id"") AND (exists(SELECT 1 
 | 
				
			||||||
            //        WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`)
 | 
					        FROM ""tag"" t 
 | 
				
			||||||
            //        limit 0, 1))
 | 
					        WHERE (t.""name"" = '国语') AND (t.""id"" = Mt_Ms.""tag_id"") 
 | 
				
			||||||
            //    limit 0, 1))
 | 
					        limit 1)) 
 | 
				
			||||||
 | 
					    limit 1))", t2);
 | 
				
			||||||
 | 
					            var t21 = fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""create_time"", a.""is_deleted"", a.""title"", a.""url"" 
 | 
				
			||||||
 | 
					FROM ""song"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""tag"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""song_tag"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""tag_id"" = t.""id"") AND (Mt_Ma.""song_id"" = a.""id"") 
 | 
				
			||||||
 | 
					        limit 1)) AND (t.""name"" = '国语') 
 | 
				
			||||||
 | 
					    limit 1))", t21);
 | 
				
			||||||
 | 
					            var t22 = fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""create_time"", a.""is_deleted"", a.""title"", a.""url"" 
 | 
				
			||||||
 | 
					FROM ""song"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""tag"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""song_tag"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""tag_id"" = t.""id"") AND (Mt_Ma.""song_id"" = a.""id"") 
 | 
				
			||||||
 | 
					        limit 1)) AND (t.""name"" = '国语') 
 | 
				
			||||||
 | 
					    limit 1))", t22);
 | 
				
			||||||
 | 
					            var t23 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a__Parent.""id"" as3, a__Parent.""parent_id"" as4, a__Parent.""ddd"", a__Parent.""name"", a.""ddd"" as7, a.""name"" as8 
 | 
				
			||||||
 | 
					FROM ""tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""tag"" a__Parent ON a__Parent.""id"" = a.""parent_id"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""song"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""song_tag"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""song_id"" = s.""id"") AND (Ms_Ma__Parent.""tag_id"" = a__Parent.""id"") 
 | 
				
			||||||
 | 
					        limit 1)) AND (s.""title"" = '中国人') 
 | 
				
			||||||
 | 
					    limit 1))", t23);
 | 
				
			||||||
 | 
					            var t24 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a__Parent.""id"" as3, a__Parent.""parent_id"" as4, a__Parent.""ddd"", a__Parent.""name"", a.""ddd"" as7, a.""name"" as8 
 | 
				
			||||||
 | 
					FROM ""tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""tag"" a__Parent ON a__Parent.""id"" = a.""parent_id"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""song"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""song_tag"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""song_id"" = s.""id"") AND (Ms_Ma__Parent.""tag_id"" = a__Parent.""id"") 
 | 
				
			||||||
 | 
					        limit 1)) AND (s.""title"" = '中国人') 
 | 
				
			||||||
 | 
					    limit 1))", t24);
 | 
				
			||||||
 | 
					            var t25 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""id"", a.""parent_id"", a__Parent.""id"" as3, a__Parent.""parent_id"" as4, a__Parent.""ddd"", a__Parent.""name"", a.""ddd"" as7, a.""name"" as8 
 | 
				
			||||||
 | 
					FROM ""tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""tag"" a__Parent ON a__Parent.""id"" = a.""parent_id"" 
 | 
				
			||||||
 | 
					WHERE (((a.""name"") in (SELECT s.""title"" as1 
 | 
				
			||||||
 | 
					    FROM ""song"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""song_tag"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""song_id"" = s.""id"") AND (Ms_Ma__Parent.""tag_id"" = a__Parent.""id"") 
 | 
				
			||||||
 | 
					        limit 1)) AND (s.""title"" = '中国人'))))", t25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var t3 = fsql.Select<Song>().ToList(r => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                r.Title,
 | 
				
			||||||
 | 
					                c2 = r.Tags.Count,
 | 
				
			||||||
 | 
					                c3 = r.Tags.Count(),
 | 
				
			||||||
 | 
					                c4 = r.Tags.Count(tag => tag.Id > 0),
 | 
				
			||||||
 | 
					                s1 = r.Tags.Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                a1 = r.Tags.Average(b => b.Id + 1),
 | 
				
			||||||
 | 
					                m1 = r.Tags.Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                m2 = r.Tags.Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                f1 = r.Tags.Select(b => b.Name).First(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                count = r.Tags.AsSelect().Count(),
 | 
				
			||||||
 | 
					                sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
				
			||||||
 | 
					                max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                first = r.Tags.AsSelect().First(b => b.Name)
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using FreeSql.Tests.DataContext.SqlServer;
 | 
					using FreeSql.Tests.DataContext.SqlServer;
 | 
				
			||||||
using NetTaste;
 | 
					using NetTaste;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
@@ -83,40 +83,145 @@ namespace FreeSql.Tests.SqlServer
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void AsSelect()
 | 
					        public void AsSelect()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.sqlserver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToOne、ManyToOne
 | 
					            //OneToOne、ManyToOne
 | 
				
			||||||
            var t0 = g.sqlserver.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
					            var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
				
			||||||
            //SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").First();
 | 
				
			||||||
            //FROM [Tag] a 
 | 
					            //Assert.Equal(@"", t0);
 | 
				
			||||||
            //LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] 
 | 
					 | 
				
			||||||
            //LEFT JOIN [Tag] a__Parent__Parent ON a__Parent__Parent.[Id] = a__Parent.[Parent_id] 
 | 
					 | 
				
			||||||
            //WHERE (a__Parent__Parent.[Name] = '粤语')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToMany
 | 
					            //OneToMany
 | 
				
			||||||
            var t1 = g.sqlserver.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
					            var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
            //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] 
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
            //FROM [Tag] a 
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] 
 | 
				
			||||||
            //WHERE (exists(SELECT 1 
 | 
					FROM [Tag] a 
 | 
				
			||||||
            //    FROM [Tag] t 
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
            //    LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] 
 | 
					    FROM [Tag] t 
 | 
				
			||||||
            //    WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) 
 | 
					    LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] 
 | 
				
			||||||
            //    limit 0,1))
 | 
					    WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id])))", t1);
 | 
				
			||||||
 | 
					            var t11 = fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a.[Id]) AND (t__Parent.[Id] = 10)))", t11);
 | 
				
			||||||
 | 
					            var t12 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a__Parent.[Id]) AND (t__Parent.[Id] = 10)))", t12);
 | 
				
			||||||
 | 
					            var t13 = fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a.[Id]) AND (t__Parent.[Id] = 10)))", t13);
 | 
				
			||||||
 | 
					            var t14 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a__Parent.[Id]) AND (t__Parent.[Id] = 10)))", t14);
 | 
				
			||||||
 | 
					            var t15 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] 
 | 
				
			||||||
 | 
					WHERE (((a.[Name]) in (SELECT t.[Name] as1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] 
 | 
				
			||||||
 | 
					    WHERE (t.[Parent_id] = a__Parent.[Id]) AND (t__Parent.[Id] = 10))))", t15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //ManyToMany
 | 
					            //ManyToMany
 | 
				
			||||||
            var t2 = g.sqlserver.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
					            var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
            //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] 
 | 
					            fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).First();
 | 
				
			||||||
            //FROM [Song] a
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] 
 | 
				
			||||||
            //WHERE(exists(SELECT 1
 | 
					FROM [Song] a 
 | 
				
			||||||
            //    FROM [Song_tag] Mt_Ms
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
            //    WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1
 | 
					    FROM [Song_tag] Mt_Ms 
 | 
				
			||||||
            //        FROM [Tag] t
 | 
					    WHERE (Mt_Ms.[Song_id] = a.[Id]) AND (exists(SELECT TOP 1 1 
 | 
				
			||||||
            //        WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id])
 | 
					        FROM [Tag] t 
 | 
				
			||||||
            //        limit 0, 1))
 | 
					        WHERE (t.[Name] = N'国语') AND (t.[Id] = Mt_Ms.[Tag_id])))))", t2);
 | 
				
			||||||
            //    limit 0, 1))
 | 
					            var t21 = fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] 
 | 
				
			||||||
 | 
					FROM [Song] a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.[Tag_id] = t.[Id]) AND (Mt_Ma.[Song_id] = a.[Id]))) AND (t.[Name] = N'国语')))", t21);
 | 
				
			||||||
 | 
					            var t22 = fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] 
 | 
				
			||||||
 | 
					FROM [Song] a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Tag] t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.[Tag_id] = t.[Id]) AND (Mt_Ma.[Song_id] = a.[Id]))) AND (t.[Name] = N'国语')))", t22);
 | 
				
			||||||
 | 
					            var t23 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Song] s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.[Song_id] = s.[Id]) AND (Ms_Ma__Parent.[Tag_id] = a__Parent.[Id]))) AND (s.[Title] = N'中国人')))", t23);
 | 
				
			||||||
 | 
					            var t24 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					    FROM [Song] s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.[Song_id] = s.[Id]) AND (Ms_Ma__Parent.[Tag_id] = a__Parent.[Id]))) AND (s.[Title] = N'中国人')))", t24);
 | 
				
			||||||
 | 
					            var t25 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 
 | 
				
			||||||
 | 
					FROM [Tag] a 
 | 
				
			||||||
 | 
					LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] 
 | 
				
			||||||
 | 
					WHERE (((a.[Name]) in (SELECT s.[Title] as1 
 | 
				
			||||||
 | 
					    FROM [Song] s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT TOP 1 1 
 | 
				
			||||||
 | 
					        FROM [Song_tag] Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.[Song_id] = s.[Id]) AND (Ms_Ma__Parent.[Tag_id] = a__Parent.[Id]))) AND (s.[Title] = N'中国人'))))", t25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var t3 = g.sqlserver.Select<Song>().ToList(r => new
 | 
					
 | 
				
			||||||
 | 
					            var t3 = fsql.Select<Song>().ToList(r => new
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                r.Title,
 | 
					                r.Title,
 | 
				
			||||||
                count = r.Tags.AsSelect().Count()
 | 
					                c2 = r.Tags.Count,
 | 
				
			||||||
 | 
					                c3 = r.Tags.Count(),
 | 
				
			||||||
 | 
					                c4 = r.Tags.Count(tag => tag.Id > 0),
 | 
				
			||||||
 | 
					                s1 = r.Tags.Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                a1 = r.Tags.Average(b => b.Id + 1),
 | 
				
			||||||
 | 
					                m1 = r.Tags.Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                m2 = r.Tags.Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                f1 = r.Tags.Select(b => b.Name).First(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                count = r.Tags.AsSelect().Count(),
 | 
				
			||||||
 | 
					                sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
				
			||||||
 | 
					                max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                first = r.Tags.AsSelect().First(b => b.Name)
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
using Newtonsoft.Json;
 | 
					using Newtonsoft.Json;
 | 
				
			||||||
using Newtonsoft.Json.Linq;
 | 
					using Newtonsoft.Json.Linq;
 | 
				
			||||||
@@ -81,45 +81,165 @@ namespace FreeSql.Tests.Sqlite
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void AsSelect()
 | 
					        public void AsSelect()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.sqlite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToOne、ManyToOne
 | 
					            //OneToOne、ManyToOne
 | 
				
			||||||
            var t0 = g.sqlite.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
					            var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a__Parent.""Id"" as3, a__Parent.""Parent_id"" as4, a__Parent.""Ddd"", a__Parent.""Name"", a.""Ddd"" as7, a.""Name"" as8 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` 
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
            //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` 
 | 
					LEFT JOIN ""Tag"" a__Parent ON a__Parent.""Id"" = a.""Parent_id"" 
 | 
				
			||||||
            //WHERE (a__Parent__Parent.`Name` = '粤语')
 | 
					LEFT JOIN ""Tag"" a__Parent__Parent ON a__Parent__Parent.""Id"" = a__Parent.""Parent_id"" 
 | 
				
			||||||
 | 
					WHERE (a__Parent__Parent.""Name"" = '粤语')", t0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //OneToMany
 | 
					            //OneToMany
 | 
				
			||||||
            var t1 = g.sqlite.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
					            var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` 
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
            //FROM `Tag` a 
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a.""Ddd"", a.""Name"" 
 | 
				
			||||||
            //WHERE (exists(SELECT 1 
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
            //    FROM `Tag` t 
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` 
 | 
					    FROM ""Tag"" t 
 | 
				
			||||||
            //    WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) 
 | 
					    LEFT JOIN ""Tag"" t__Parent ON t__Parent.""Id"" = t.""Parent_id"" 
 | 
				
			||||||
            //    limit 0,1))
 | 
					    WHERE (t__Parent.""Id"" = 10) AND (t.""Parent_id"" = a.""Id"") 
 | 
				
			||||||
 | 
					    limit 0,1))", t1);
 | 
				
			||||||
 | 
					            var t11 = fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a.""Ddd"", a.""Name"" 
 | 
				
			||||||
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""Tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""Tag"" t__Parent ON t__Parent.""Id"" = t.""Parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""Parent_id"" = a.""Id"") AND (t__Parent.""Id"" = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t11);
 | 
				
			||||||
 | 
					            var t12 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Any(t => t.Parent.Id == 10)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a__Parent.""Id"" as3, a__Parent.""Parent_id"" as4, a__Parent.""Ddd"", a__Parent.""Name"", a.""Ddd"" as7, a.""Name"" as8 
 | 
				
			||||||
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""Tag"" a__Parent ON a__Parent.""Id"" = a.""Parent_id"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""Tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""Tag"" t__Parent ON t__Parent.""Id"" = t.""Parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""Parent_id"" = a__Parent.""Id"") AND (t__Parent.""Id"" = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t12);
 | 
				
			||||||
 | 
					            var t13 = fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a.""Ddd"", a.""Name"" 
 | 
				
			||||||
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""Tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""Tag"" t__Parent ON t__Parent.""Id"" = t.""Parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""Parent_id"" = a.""Id"") AND (t__Parent.""Id"" = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t13);
 | 
				
			||||||
 | 
					            var t14 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a__Parent.""Id"" as3, a__Parent.""Parent_id"" as4, a__Parent.""Ddd"", a__Parent.""Name"", a.""Ddd"" as7, a.""Name"" as8 
 | 
				
			||||||
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""Tag"" a__Parent ON a__Parent.""Id"" = a.""Parent_id"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""Tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""Tag"" t__Parent ON t__Parent.""Id"" = t.""Parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""Parent_id"" = a__Parent.""Id"") AND (t__Parent.""Id"" = 10) 
 | 
				
			||||||
 | 
					    limit 0,1))", t14);
 | 
				
			||||||
 | 
					            var t15 = fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(a => a.Parent.Tags.Where(t => t.Parent.Id == 10).Select(t => t.Name).ToList().Contains(a.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a__Parent.""Id"" as3, a__Parent.""Parent_id"" as4, a__Parent.""Ddd"", a__Parent.""Name"", a.""Ddd"" as7, a.""Name"" as8 
 | 
				
			||||||
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""Tag"" a__Parent ON a__Parent.""Id"" = a.""Parent_id"" 
 | 
				
			||||||
 | 
					WHERE (((a.""Name"") in (SELECT t.""Name"" as1 
 | 
				
			||||||
 | 
					    FROM ""Tag"" t 
 | 
				
			||||||
 | 
					    LEFT JOIN ""Tag"" t__Parent ON t__Parent.""Id"" = t.""Parent_id"" 
 | 
				
			||||||
 | 
					    WHERE (t.""Parent_id"" = a__Parent.""Id"") AND (t__Parent.""Id"" = 10))))", t15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //ManyToMany
 | 
					            //ManyToMany
 | 
				
			||||||
            var t2 = g.sqlite.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
					            var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
            //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` 
 | 
					            fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).First();
 | 
				
			||||||
            //FROM `Song` a
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Create_time"", a.""Is_deleted"", a.""Title"", a.""Url"" 
 | 
				
			||||||
            //WHERE(exists(SELECT 1
 | 
					FROM ""Song"" a 
 | 
				
			||||||
            //    FROM `Song_tag` Mt_Ms
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
            //    WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1
 | 
					    FROM ""Song_tag"" Mt_Ms 
 | 
				
			||||||
            //        FROM `Tag` t
 | 
					    WHERE (Mt_Ms.""Song_id"" = a.""Id"") AND (exists(SELECT 1 
 | 
				
			||||||
            //        WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`)
 | 
					        FROM ""Tag"" t 
 | 
				
			||||||
            //        limit 0, 1))
 | 
					        WHERE (t.""Name"" = '国语') AND (t.""Id"" = Mt_Ms.""Tag_id"") 
 | 
				
			||||||
            //    limit 0, 1))
 | 
					        limit 0,1)) 
 | 
				
			||||||
 | 
					    limit 0,1))", t2);
 | 
				
			||||||
 | 
					            var t21 = fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Any(t => t.Name == "国语")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Create_time"", a.""Is_deleted"", a.""Title"", a.""Url"" 
 | 
				
			||||||
 | 
					FROM ""Song"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""Tag"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""Song_tag"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""Tag_id"" = t.""Id"") AND (Mt_Ma.""Song_id"" = a.""Id"") 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (t.""Name"" = '国语') 
 | 
				
			||||||
 | 
					    limit 0,1))", t21);
 | 
				
			||||||
 | 
					            var t22 = fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Song>().Where(s => s.Tags.Where(t => t.Name == "国语").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Create_time"", a.""Is_deleted"", a.""Title"", a.""Url"" 
 | 
				
			||||||
 | 
					FROM ""Song"" a 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""Tag"" t 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""Song_tag"" Mt_Ma 
 | 
				
			||||||
 | 
					        WHERE (Mt_Ma.""Tag_id"" = t.""Id"") AND (Mt_Ma.""Song_id"" = a.""Id"") 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (t.""Name"" = '国语') 
 | 
				
			||||||
 | 
					    limit 0,1))", t22);
 | 
				
			||||||
 | 
					            var t23 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Any(s => s.Title == "中国人")).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a__Parent.""Id"" as3, a__Parent.""Parent_id"" as4, a__Parent.""Ddd"", a__Parent.""Name"", a.""Ddd"" as7, a.""Name"" as8 
 | 
				
			||||||
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""Tag"" a__Parent ON a__Parent.""Id"" = a.""Parent_id"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""Song"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""Song_tag"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""Song_id"" = s.""Id"") AND (Ms_Ma__Parent.""Tag_id"" = a__Parent.""Id"") 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (s.""Title"" = '中国人') 
 | 
				
			||||||
 | 
					    limit 0,1))", t23);
 | 
				
			||||||
 | 
					            var t24 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).ToSql();
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Any()).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a__Parent.""Id"" as3, a__Parent.""Parent_id"" as4, a__Parent.""Ddd"", a__Parent.""Name"", a.""Ddd"" as7, a.""Name"" as8 
 | 
				
			||||||
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""Tag"" a__Parent ON a__Parent.""Id"" = a.""Parent_id"" 
 | 
				
			||||||
 | 
					WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					    FROM ""Song"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""Song_tag"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""Song_id"" = s.""Id"") AND (Ms_Ma__Parent.""Tag_id"" = a__Parent.""Id"") 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (s.""Title"" = '中国人') 
 | 
				
			||||||
 | 
					    limit 0,1))", t24);
 | 
				
			||||||
 | 
					            var t25 = fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).ToSql(); 
 | 
				
			||||||
 | 
					            fsql.Select<Tag>().Where(t => t.Parent.Songs.Where(s => s.Title == "中国人").Select(s => s.Title).ToList().Contains(t.Name)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""Id"", a.""Parent_id"", a__Parent.""Id"" as3, a__Parent.""Parent_id"" as4, a__Parent.""Ddd"", a__Parent.""Name"", a.""Ddd"" as7, a.""Name"" as8 
 | 
				
			||||||
 | 
					FROM ""Tag"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""Tag"" a__Parent ON a__Parent.""Id"" = a.""Parent_id"" 
 | 
				
			||||||
 | 
					WHERE (((a.""Name"") in (SELECT s.""Title"" as1 
 | 
				
			||||||
 | 
					    FROM ""Song"" s 
 | 
				
			||||||
 | 
					    WHERE (exists(SELECT 1 
 | 
				
			||||||
 | 
					        FROM ""Song_tag"" Ms_Ma__Parent 
 | 
				
			||||||
 | 
					        WHERE (Ms_Ma__Parent.""Song_id"" = s.""Id"") AND (Ms_Ma__Parent.""Tag_id"" = a__Parent.""Id"") 
 | 
				
			||||||
 | 
					        limit 0,1)) AND (s.""Title"" = '中国人'))))", t25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var t3 = g.sqlite.Select<Song>().ToList(r => new
 | 
					
 | 
				
			||||||
 | 
					            var t3 = fsql.Select<Song>().ToList(r => new
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                r.Title,
 | 
					                r.Title,
 | 
				
			||||||
 | 
					                c2 = r.Tags.Count,
 | 
				
			||||||
 | 
					                c3 = r.Tags.Count(),
 | 
				
			||||||
 | 
					                c4 = r.Tags.Count(tag => tag.Id > 0),
 | 
				
			||||||
 | 
					                s1 = r.Tags.Sum(b => b.Id + 0),
 | 
				
			||||||
 | 
					                a1 = r.Tags.Average(b => b.Id + 1),
 | 
				
			||||||
 | 
					                m1 = r.Tags.Max(b => b.Id + 2),
 | 
				
			||||||
 | 
					                m2 = r.Tags.Min(b => b.Id + 3),
 | 
				
			||||||
 | 
					                f1 = r.Tags.Select(b => b.Name).First(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                count = r.Tags.AsSelect().Count(),
 | 
					                count = r.Tags.AsSelect().Count(),
 | 
				
			||||||
                //sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
					                sum = r.Tags.AsSelect().Sum(b => b.Id + 0),
 | 
				
			||||||
                //avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
					                avg = r.Tags.AsSelect().Avg(b => b.Id + 1),
 | 
				
			||||||
                //max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
					                max = r.Tags.AsSelect().Max(b => b.Id + 2),
 | 
				
			||||||
                //min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
					                min = r.Tags.AsSelect().Min(b => b.Id + 3),
 | 
				
			||||||
                //first = r.Tags.AsSelect().First(b => b.Name)
 | 
					                first = r.Tags.AsSelect().First(b => b.Name)
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -227,7 +227,7 @@ namespace System.Linq.Expressions
 | 
				
			|||||||
        public static Expression<Func<T1, T2, T3, T4, T5, bool>> Not<T1, T2, T3, T4, T5>(this Expression<Func<T1, T2, T3, T4, T5, bool>> exp, bool condition = true) => (Expression<Func<T1, T2, T3, T4, T5, bool>>)InternalNotExpression(condition, exp);
 | 
					        public static Expression<Func<T1, T2, T3, T4, T5, bool>> Not<T1, T2, T3, T4, T5>(this Expression<Func<T1, T2, T3, T4, T5, bool>> exp, bool condition = true) => (Expression<Func<T1, T2, T3, T4, T5, bool>>)InternalNotExpression(condition, exp);
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static bool IsParameter(this Expression exp)
 | 
					        public static bool IsParameter(this Expression exp)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var test = new TestParameterExpressionVisitor();
 | 
					            var test = new TestParameterExpressionVisitor();
 | 
				
			||||||
            test.Visit(exp);
 | 
					            test.Visit(exp);
 | 
				
			||||||
@@ -258,6 +258,72 @@ namespace System.Linq.Expressions
 | 
				
			|||||||
            toListArgs0Out = null;
 | 
					            toListArgs0Out = null;
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static object GetConstExprValue(this Expression exp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (exp.IsParameter()) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var expStack = new Stack<Expression>();
 | 
				
			||||||
 | 
					            var exp2 = exp;
 | 
				
			||||||
 | 
					            while (true)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                switch (exp2?.NodeType)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    case ExpressionType.Constant:
 | 
				
			||||||
 | 
					                        expStack.Push(exp2);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case ExpressionType.MemberAccess:
 | 
				
			||||||
 | 
					                        expStack.Push(exp2);
 | 
				
			||||||
 | 
					                        exp2 = (exp2 as MemberExpression).Expression;
 | 
				
			||||||
 | 
					                        if (exp2 == null) break;
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    case ExpressionType.Call:
 | 
				
			||||||
 | 
					                        return Expression.Lambda(exp).Compile().DynamicInvoke();
 | 
				
			||||||
 | 
					                    case ExpressionType.TypeAs:
 | 
				
			||||||
 | 
					                    case ExpressionType.Convert:
 | 
				
			||||||
 | 
					                        var oper2 = (exp2 as UnaryExpression).Operand;
 | 
				
			||||||
 | 
					                        if (oper2.NodeType == ExpressionType.Parameter)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            var oper2Parm = oper2 as ParameterExpression;
 | 
				
			||||||
 | 
					                            expStack.Push(exp2.Type.IsAbstract || exp2.Type.IsInterface ? oper2Parm : Expression.Parameter(exp2.Type, oper2Parm.Name));
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                            expStack.Push(oper2);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            object firstValue = null;
 | 
				
			||||||
 | 
					            switch (expStack.First().NodeType)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                case ExpressionType.Constant:
 | 
				
			||||||
 | 
					                    var expStackFirst = expStack.Pop() as ConstantExpression;
 | 
				
			||||||
 | 
					                    firstValue = expStackFirst?.Value;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case ExpressionType.MemberAccess:
 | 
				
			||||||
 | 
					                    var expStackFirstMem = expStack.First() as MemberExpression;
 | 
				
			||||||
 | 
					                    if (expStackFirstMem.Expression?.NodeType == ExpressionType.Constant)
 | 
				
			||||||
 | 
					                        firstValue = (expStackFirstMem.Expression as ConstantExpression)?.Value;
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                        return Expression.Lambda(exp).Compile().DynamicInvoke();
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            while (expStack.Any())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var expStackItem = expStack.Pop();
 | 
				
			||||||
 | 
					                switch (expStackItem.NodeType)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    case ExpressionType.MemberAccess:
 | 
				
			||||||
 | 
					                        var memExp = expStackItem as MemberExpression;
 | 
				
			||||||
 | 
					                        if (memExp.Member.MemberType == MemberTypes.Property)
 | 
				
			||||||
 | 
					                            firstValue = ((PropertyInfo)memExp.Member).GetValue(firstValue, null);
 | 
				
			||||||
 | 
					                        else if (memExp.Member.MemberType == MemberTypes.Field)
 | 
				
			||||||
 | 
					                            firstValue = ((FieldInfo)memExp.Member).GetValue(firstValue);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return firstValue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    internal class NewExpressionVisitor : ExpressionVisitor
 | 
					    internal class NewExpressionVisitor : ExpressionVisitor
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3249,6 +3249,177 @@
 | 
				
			|||||||
            <param name="parms"></param>
 | 
					            <param name="parms"></param>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteConnectTestAsync(System.Int32,System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            测试数据库是否连接正确,本方法执行如下命令:<para></para>
 | 
				
			||||||
 | 
					            MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1<para></para>
 | 
				
			||||||
 | 
					            Oracle: SELECT 1 FROM dual<para></para>
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="commandTimeout">命令超时设置(秒)</param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns>true: 成功, false: 失败</returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{FreeSql.Internal.Model.FetchCallbackArgs{System.Data.Common.DbDataReader},System.Threading.Tasks.Task},System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="readerHander"></param>
 | 
				
			||||||
 | 
					            <param name="cmdType"></param>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="cmdParms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{FreeSql.Internal.Model.FetchCallbackArgs{System.Data.Common.DbDataReader},System.Threading.Tasks.Task},System.String,System.Object,System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 })<para></para>
 | 
				
			||||||
 | 
					            提示:parms 参数还可以传 Dictionary<string, object>
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="readerHander"></param>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="parms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            查询
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdType"></param>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="cmdParms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.String,System.Object,System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 })<para></para>
 | 
				
			||||||
 | 
					            提示:parms 参数还可以传 Dictionary<string, object>
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="parms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            查询
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdType"></param>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="cmdParms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.String,System.Object,System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 })<para></para>
 | 
				
			||||||
 | 
					            提示:parms 参数还可以传 Dictionary<string, object>
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="parms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            查询
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdType"></param>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="cmdParms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.String,System.Object,System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 })<para></para>
 | 
				
			||||||
 | 
					            提示:parms 参数还可以传 Dictionary<string, object>
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="parms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            在【主库】执行
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdType"></param>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="cmdParms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.String,System.Object,System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 })<para></para>
 | 
				
			||||||
 | 
					            提示:parms 参数还可以传 Dictionary<string, object>
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="parms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            在【主库】执行
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdType"></param>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="cmdParms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.String,System.Object,System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 })<para></para>
 | 
				
			||||||
 | 
					            提示:parms 参数还可以传 Dictionary<string, object>
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="parms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.QueryAsync``1(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            执行SQL返回对象集合,QueryAsync<User>("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>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.QueryAsync``1(System.String,System.Object,System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 })<para></para>
 | 
				
			||||||
 | 
					            提示:parms 参数还可以传 Dictionary<string, object>
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <typeparam name="T"></typeparam>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="parms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.QueryAsync``2(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 })
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <typeparam name="T1"></typeparam>
 | 
				
			||||||
 | 
					            <typeparam name="T2"></typeparam>
 | 
				
			||||||
 | 
					            <param name="cmdType"></param>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="cmdParms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.IAdo.QueryAsync``2(System.String,System.Object,System.Threading.CancellationToken)">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            执行SQL返回对象集合,Query<User, Address>("select * from user where age > @age; select * from address", new { age = 25 })<para></para>
 | 
				
			||||||
 | 
					            提示:parms 参数还可以传 Dictionary<string, object>
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <typeparam name="T1"></typeparam>
 | 
				
			||||||
 | 
					            <typeparam name="T2"></typeparam>
 | 
				
			||||||
 | 
					            <param name="cmdText"></param>
 | 
				
			||||||
 | 
					            <param name="parms"></param>
 | 
				
			||||||
 | 
					            <param name="cancellationToken"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
        <member name="E:FreeSql.IAop.ParseExpression">
 | 
					        <member name="E:FreeSql.IAop.ParseExpression">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            可自定义解析表达式
 | 
					            可自定义解析表达式
 | 
				
			||||||
@@ -4143,6 +4314,12 @@
 | 
				
			|||||||
            <param name="timeout">超时</param>
 | 
					            <param name="timeout">超时</param>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </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)">
 | 
					        <member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.Return(FreeSql.Internal.ObjectPool.Object{`0},System.Boolean)">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            使用完毕后,归还资源
 | 
					            使用完毕后,归还资源
 | 
				
			||||||
@@ -4218,6 +4395,12 @@
 | 
				
			|||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
            <param name="obj">资源对象</param>
 | 
					            <param name="obj">资源对象</param>
 | 
				
			||||||
        </member>
 | 
					        </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})">
 | 
					        <member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnReturn(FreeSql.Internal.ObjectPool.Object{`0})">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            归还对象给对象池的时候触发
 | 
					            归还对象给对象池的时候触发
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,12 +92,15 @@ namespace FreeSql.Aop
 | 
				
			|||||||
    #region ParseExpression
 | 
					    #region ParseExpression
 | 
				
			||||||
    public class ParseExpressionEventArgs : EventArgs
 | 
					    public class ParseExpressionEventArgs : EventArgs
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public ParseExpressionEventArgs(Expression expression, Func<Expression, string> freeParse)
 | 
					        public ParseExpressionEventArgs(Expression expression, Func<Expression, string> freeParse, List<SelectTableInfo> tables)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            this.Expression = expression;
 | 
					            this.Expression = expression;
 | 
				
			||||||
            this.FreeParse = freeParse;
 | 
					            this.FreeParse = freeParse;
 | 
				
			||||||
 | 
					            this.Tables = tables;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public List<SelectTableInfo> Tables { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 内置解析功能,可辅助您进行解析
 | 
					        /// 内置解析功能,可辅助您进行解析
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -714,10 +714,15 @@ namespace FreeSql.Internal
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            if (exp == null) return "";
 | 
					            if (exp == null) return "";
 | 
				
			||||||
            if (tsc.dbParams != null && tsc.mapColumnTmp != null && tsc.mapColumnTmp.CsType.NullableTypeOrThis() != exp.Type) tsc.SetMapColumnTmp(null);
 | 
					            if (tsc.dbParams != null && tsc.mapColumnTmp != null && tsc.mapColumnTmp.CsType.NullableTypeOrThis() != exp.Type) tsc.SetMapColumnTmp(null);
 | 
				
			||||||
            if (tsc.isDisableDiyParse == false && _common._orm.Aop.ParseExpressionHandler != null)
 | 
					            if (tsc.isDisableDiyParse == false)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(ukexp, tsc.CloneDisableDiyParse()));
 | 
					                var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(ukexp, tsc.CloneDisableDiyParse()), tsc._tables);
 | 
				
			||||||
                _common._orm.Aop.ParseExpressionHandler?.Invoke(this, args);
 | 
					                if (_common._orm.Aop.ParseExpressionHandler != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _common._orm.Aop.ParseExpressionHandler(this, args);
 | 
				
			||||||
 | 
					                    if (string.IsNullOrEmpty(args.Result) == false) return args.Result;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ParseExpressionNoAsSelect(this, args);
 | 
				
			||||||
                if (string.IsNullOrEmpty(args.Result) == false) return args.Result;
 | 
					                if (string.IsNullOrEmpty(args.Result) == false) return args.Result;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            switch (exp.NodeType)
 | 
					            switch (exp.NodeType)
 | 
				
			||||||
@@ -1240,6 +1245,26 @@ namespace FreeSql.Internal
 | 
				
			|||||||
                                                        tsc3._tables = tsc._tables.ToList();
 | 
					                                                        tsc3._tables = tsc._tables.ToList();
 | 
				
			||||||
                                                        var where2 = ExpressionLambdaToSql(Expression.Lambda(manySubSelectWhereExp, manySubSelectWhereParam), tsc3);
 | 
					                                                        var where2 = ExpressionLambdaToSql(Expression.Lambda(manySubSelectWhereExp, manySubSelectWhereParam), tsc3);
 | 
				
			||||||
                                                        if (string.IsNullOrEmpty(where2) == false) fsqls0p._where.Append(" AND (").Append(where2).Append(")");
 | 
					                                                        if (string.IsNullOrEmpty(where2) == false) fsqls0p._where.Append(" AND (").Append(where2).Append(")");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                                        switch (exp3.Method.Name)
 | 
				
			||||||
 | 
					                                                        {
 | 
				
			||||||
 | 
					                                                            case "Sum":
 | 
				
			||||||
 | 
					                                                            case "Min":
 | 
				
			||||||
 | 
					                                                            case "Max":
 | 
				
			||||||
 | 
					                                                            case "Avg":
 | 
				
			||||||
 | 
					                                                                var map = new ReadAnonymousTypeInfo();
 | 
				
			||||||
 | 
					                                                                var field = new StringBuilder();
 | 
				
			||||||
 | 
					                                                                var index = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                                                for (var a = 0; a < exp3Args0.Parameters.Count; a++) fsqls0p._tables[a].Parameter = exp3Args0.Parameters[a];
 | 
				
			||||||
 | 
					                                                                ReadAnonymousField(fsqls0p._tables, field, map, ref index, exp3Args0, null, null, null, null, false);
 | 
				
			||||||
 | 
					                                                                var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                                                var sql4 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({fieldSql})" })?.ToString();
 | 
				
			||||||
 | 
					                                                                asSelectBefores.Clear();
 | 
				
			||||||
 | 
					                                                                return $"({sql4.Replace(" \r\n", " \r\n    ")})";
 | 
				
			||||||
 | 
					                                                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                                        var sql3 = manySubSelectAggMethod.Invoke(fsql, new object[] { exp3Args0, FieldAliasOptions.AsProperty }) as string;
 | 
					                                                        var sql3 = manySubSelectAggMethod.Invoke(fsql, new object[] { exp3Args0, FieldAliasOptions.AsProperty }) as string;
 | 
				
			||||||
                                                        asSelectBefores.Clear();
 | 
					                                                        asSelectBefores.Clear();
 | 
				
			||||||
                                                        return $"({sql3.Replace(" \r\n", " \r\n    ")})";
 | 
					                                                        return $"({sql3.Replace(" \r\n", " \r\n    ")})";
 | 
				
			||||||
@@ -1900,5 +1925,283 @@ namespace FreeSql.Internal
 | 
				
			|||||||
            return string.Format(CultureInfo.InvariantCulture, "{0}", _ado.AddslashesProcessParam(obj, mapType, mapColumn));
 | 
					            return string.Format(CultureInfo.InvariantCulture, "{0}", _ado.AddslashesProcessParam(obj, mapType, mapColumn));
 | 
				
			||||||
            //return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn));
 | 
					            //return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void ParseExpressionNoAsSelect(object sender, Aop.ParseExpressionEventArgs e)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (e.Expression.NodeType != ExpressionType.Call &&
 | 
				
			||||||
 | 
					                (e.Expression as MemberExpression)?.Member.Name != "Count") return;
 | 
				
			||||||
 | 
					            var exp3Stack = new Stack<Expression>();
 | 
				
			||||||
 | 
					            var exp3tmp = e.Expression;
 | 
				
			||||||
 | 
					            while (exp3tmp != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exp3Stack.Push(exp3tmp);
 | 
				
			||||||
 | 
					                switch (exp3tmp.NodeType)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    case ExpressionType.Call:
 | 
				
			||||||
 | 
					                        var exp3tmpCall = (exp3tmp as MethodCallExpression);
 | 
				
			||||||
 | 
					                        if (exp3tmpCall.Type.FullName.StartsWith("FreeSql.ISelect`") && exp3tmpCall.Method.Name == "AsSelect" && exp3tmpCall.Object == null) return;
 | 
				
			||||||
 | 
					                        exp3tmp = exp3tmpCall.Object == null ? exp3tmpCall.Arguments.FirstOrDefault() : exp3tmpCall.Object;
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    case ExpressionType.MemberAccess:
 | 
				
			||||||
 | 
					                        exp3tmp = (exp3tmp as MemberExpression).Expression;
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    case ExpressionType.Parameter:
 | 
				
			||||||
 | 
					                        exp3tmp = null;
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            exp3tmp = exp3Stack.Pop();
 | 
				
			||||||
 | 
					            if (exp3tmp.NodeType != ExpressionType.Parameter) return;
 | 
				
			||||||
 | 
					            if (exp3tmp.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate")) return;
 | 
				
			||||||
 | 
					            var commonExp = sender as FreeSql.Internal.CommonExpression;
 | 
				
			||||||
 | 
					            if (commonExp == null) return;
 | 
				
			||||||
 | 
					            var exp3Tb = commonExp._common.GetTableByEntity(exp3tmp.Type);
 | 
				
			||||||
 | 
					            if (exp3Tb == null) return;
 | 
				
			||||||
 | 
					            var paramExp = exp3tmp as ParameterExpression;
 | 
				
			||||||
 | 
					            Select1Provider<object> select = null;
 | 
				
			||||||
 | 
					            TableRef memberTbref = null;
 | 
				
			||||||
 | 
					            MemberExpression memberExp = null;
 | 
				
			||||||
 | 
					            bool selectSetAliased = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void LocalSetSelectProviderAlias(string alias)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (selectSetAliased) return;
 | 
				
			||||||
 | 
					                selectSetAliased = true;
 | 
				
			||||||
 | 
					                select._tables[0].Alias = alias;
 | 
				
			||||||
 | 
					                select._tables[0].AliasInit = alias;
 | 
				
			||||||
 | 
					                switch (memberTbref.RefType)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    case TableRefType.ManyToMany:
 | 
				
			||||||
 | 
					                        var mtmReftbname = e.FreeParse(Expression.MakeMemberAccess(memberExp.Expression, exp3Tb.Properties[exp3Tb.ColumnsByPosition[0].CsName]));
 | 
				
			||||||
 | 
					                        mtmReftbname = mtmReftbname.Substring(0, mtmReftbname.Length - commonExp._common.QuoteSqlName(exp3Tb.ColumnsByPosition[0].Attribute.Name).Length - 1);
 | 
				
			||||||
 | 
					                        var midSelect = commonExp._common._orm.Select<object>().As($"M{select._tables[0].Alias}_M{mtmReftbname}").AsType(memberTbref.RefMiddleEntityType) as Select1Provider<object>;
 | 
				
			||||||
 | 
					                        switch (commonExp._ado.DataType)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            case DataType.Oracle:
 | 
				
			||||||
 | 
					                            case DataType.OdbcOracle:
 | 
				
			||||||
 | 
					                            case DataType.Dameng:
 | 
				
			||||||
 | 
					                            case DataType.OdbcDameng:
 | 
				
			||||||
 | 
					                            case DataType.GBase:
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            default:
 | 
				
			||||||
 | 
					                                midSelect.Limit(1); //#462 ORACLE rownum <= 2 会影响索引变慢
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        for (var tidx = 0; tidx < memberTbref.RefColumns.Count; tidx++)
 | 
				
			||||||
 | 
					                            midSelect.Where($"{midSelect._tables[0].Alias}.{commonExp._common.QuoteSqlName(memberTbref.MiddleColumns[memberTbref.Columns.Count + tidx].Attribute.Name)} = {select._tables[0].Alias}.{commonExp._common.QuoteSqlName(memberTbref.RefColumns[tidx].Attribute.Name)}");
 | 
				
			||||||
 | 
					                        for (var tidx = 0; tidx < memberTbref.Columns.Count; tidx++)
 | 
				
			||||||
 | 
					                            midSelect.Where($"{midSelect._tables[0].Alias}.{commonExp._common.QuoteSqlName(memberTbref.MiddleColumns[tidx].Attribute.Name)} = {mtmReftbname}.{commonExp._common.QuoteSqlName(memberTbref.Columns[tidx].Attribute.Name)}");
 | 
				
			||||||
 | 
					                        select.Where($"exists({midSelect.ToSql("1").Replace(" \r\n", " \r\n    ")})");
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case TableRefType.OneToMany:
 | 
				
			||||||
 | 
					                        var omtReftbname = e.FreeParse(Expression.MakeMemberAccess(memberExp.Expression, exp3Tb.Properties[exp3Tb.ColumnsByPosition[0].CsName]));
 | 
				
			||||||
 | 
					                        omtReftbname = omtReftbname.Substring(0, omtReftbname.Length - commonExp._common.QuoteSqlName(exp3Tb.ColumnsByPosition[0].Attribute.Name).Length - 1);
 | 
				
			||||||
 | 
					                        for (var tidx = 0; tidx < memberTbref.Columns.Count; tidx++)
 | 
				
			||||||
 | 
					                            select.Where($"{select._tables[0].Alias}.{commonExp._common.QuoteSqlName(memberTbref.RefColumns[tidx].Attribute.Name)} = {omtReftbname}.{commonExp._common.QuoteSqlName(memberTbref.Columns[tidx].Attribute.Name)}");
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            void LocalInitSelectProvider()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                select = commonExp._common._orm.Select<object>().AsType(memberTbref.RefEntityType) as Select1Provider<object>;
 | 
				
			||||||
 | 
					                select._tables.AddRange(e.Tables.Select(a => new SelectTableInfo
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Alias = a.Alias,
 | 
				
			||||||
 | 
					                    On = "1=1",
 | 
				
			||||||
 | 
					                    Table = a.Table,
 | 
				
			||||||
 | 
					                    Type = SelectTableInfoType.Parent,
 | 
				
			||||||
 | 
					                    Parameter = a.Parameter
 | 
				
			||||||
 | 
					                }));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            while (true)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var exp4 = exp3Stack.Pop();
 | 
				
			||||||
 | 
					                if (exp4.NodeType == ExpressionType.MemberAccess)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var tmpExp = exp4 as MemberExpression;
 | 
				
			||||||
 | 
					                    if (tmpExp.Member.Name == "Count" && select != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        if (exp3Stack.Any()) return;
 | 
				
			||||||
 | 
					                        LocalSetSelectProviderAlias("tbcou");
 | 
				
			||||||
 | 
					                        e.Result = $"({select.ToSql("count(1)").Replace(" \r\n", " \r\n    ")})";
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (select != null) return;
 | 
				
			||||||
 | 
					                    memberExp = tmpExp;
 | 
				
			||||||
 | 
					                    memberTbref = exp3Tb.GetTableRef(memberExp.Member.Name, false);
 | 
				
			||||||
 | 
					                    if (memberTbref == null) return;
 | 
				
			||||||
 | 
					                    switch (memberTbref.RefType)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        case TableRefType.ManyToOne:
 | 
				
			||||||
 | 
					                        case TableRefType.OneToOne:
 | 
				
			||||||
 | 
					                            exp3Tb = commonExp._common.GetTableByEntity(memberExp.Type);
 | 
				
			||||||
 | 
					                            if (exp3Tb == null) return;
 | 
				
			||||||
 | 
					                            continue;
 | 
				
			||||||
 | 
					                        case TableRefType.ManyToMany:
 | 
				
			||||||
 | 
					                            if (select != null) return;
 | 
				
			||||||
 | 
					                            LocalInitSelectProvider();
 | 
				
			||||||
 | 
					                            continue;
 | 
				
			||||||
 | 
					                        case TableRefType.OneToMany:
 | 
				
			||||||
 | 
					                            if (select != null) return;
 | 
				
			||||||
 | 
					                            LocalInitSelectProvider();
 | 
				
			||||||
 | 
					                            continue;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (exp4.NodeType == ExpressionType.Call)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (select == null) return;
 | 
				
			||||||
 | 
					                    var callExp = exp4 as MethodCallExpression;
 | 
				
			||||||
 | 
					                    switch (callExp.Method.Name)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        case "Any":
 | 
				
			||||||
 | 
					                            if (callExp.Arguments.Count == 2)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                select._tables[0].Parameter = (callExp.Arguments[1] as LambdaExpression)?.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                                LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					                                select.InternalWhere(callExp.Arguments[1]);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            switch (commonExp._ado.DataType)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                case DataType.Oracle:
 | 
				
			||||||
 | 
					                                case DataType.OdbcOracle:
 | 
				
			||||||
 | 
					                                case DataType.Dameng:
 | 
				
			||||||
 | 
					                                case DataType.OdbcDameng:
 | 
				
			||||||
 | 
					                                case DataType.GBase:
 | 
				
			||||||
 | 
					                                    break;
 | 
				
			||||||
 | 
					                                default:
 | 
				
			||||||
 | 
					                                    select._limit = 1; //#462 ORACLE rownum <= 2 会影响索引变慢
 | 
				
			||||||
 | 
					                                    break;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            if (exp3Stack.Any()) return;
 | 
				
			||||||
 | 
					                            LocalSetSelectProviderAlias("tbany");
 | 
				
			||||||
 | 
					                            e.Result = $"exists({select.ToSql("1").Replace(" \r\n", " \r\n    ")})";
 | 
				
			||||||
 | 
					                            return;
 | 
				
			||||||
 | 
					                        case "Max":
 | 
				
			||||||
 | 
					                        case "Min":
 | 
				
			||||||
 | 
					                        case "Sum":
 | 
				
			||||||
 | 
					                        case "Average":
 | 
				
			||||||
 | 
					                            if (callExp.Arguments.Count == 2)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                var aggregateMethodName = callExp.Method.Name == "Average" ? "avg" : callExp.Method.Name.ToLower();
 | 
				
			||||||
 | 
					                                if (exp3Stack.Any()) return;
 | 
				
			||||||
 | 
					                                select._tables[0].Parameter = (callExp.Arguments[1] as LambdaExpression)?.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                                LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                var map = new ReadAnonymousTypeInfo();
 | 
				
			||||||
 | 
					                                var field = new StringBuilder();
 | 
				
			||||||
 | 
					                                var index = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                commonExp.ReadAnonymousField(select._tables, field, map, ref index, callExp.Arguments[1], null, null, null, null, false);
 | 
				
			||||||
 | 
					                                var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                e.Result = $"({select.ToSql($"{aggregateMethodName}({fieldSql})").Replace(" \r\n", " \r\n    ")})";
 | 
				
			||||||
 | 
					                                return;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            throw throwCallExp($"不支持 {callExp.Arguments.Count}个参数的方法");
 | 
				
			||||||
 | 
					                        case "Count":
 | 
				
			||||||
 | 
					                            if (callExp.Arguments.Count == 2)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                select._tables[0].Parameter = (callExp.Arguments[1] as LambdaExpression)?.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                                LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					                                select.InternalWhere(callExp.Arguments[1]);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            if (exp3Stack.Any()) return;
 | 
				
			||||||
 | 
					                            LocalSetSelectProviderAlias("tbcou");
 | 
				
			||||||
 | 
					                            e.Result = $"({select.ToSql("count(1)").Replace(" \r\n", " \r\n    ")})";
 | 
				
			||||||
 | 
					                            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case "First":
 | 
				
			||||||
 | 
					                            select.Limit(1);
 | 
				
			||||||
 | 
					                            if (callExp.Arguments.Count == 1)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                if (exp3Stack.Any()) return;
 | 
				
			||||||
 | 
					                                LocalSetSelectProviderAlias("tbfirst");
 | 
				
			||||||
 | 
					                                e.Result = $"({select.ToSql().Replace(" \r\n", " \r\n    ")})";
 | 
				
			||||||
 | 
					                                return;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            throw throwCallExp(" 不支持");
 | 
				
			||||||
 | 
					                        case "ToList":
 | 
				
			||||||
 | 
					                            if (callExp.Arguments.Count == 1)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                if (exp3Stack.Any()) return;
 | 
				
			||||||
 | 
					                                LocalSetSelectProviderAlias("tbtolist");
 | 
				
			||||||
 | 
					                                e.Result = $"({select.ToSql().Replace(" \r\n", " \r\n    ")})";
 | 
				
			||||||
 | 
					                                return;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            throw throwCallExp(" 不支持");
 | 
				
			||||||
 | 
					                        case "Contains":
 | 
				
			||||||
 | 
					                            if (callExp.Arguments.Count == 2)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                if (exp3Stack.Any()) return;
 | 
				
			||||||
 | 
					                                select._tables[0].Parameter = (callExp.Arguments[1] as LambdaExpression)?.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                                LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					                                e.Result = $"({e.FreeParse(callExp.Arguments[1])}) in {select.ToSql().Replace(" \r\n", " \r\n    ")})";
 | 
				
			||||||
 | 
					                                return;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            throw throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case "Distinct":
 | 
				
			||||||
 | 
					                            if (callExp.Arguments.Count == 1)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                select.Distinct();
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            throw throwCallExp(" 不支持");
 | 
				
			||||||
 | 
					                        case "OrderBy":
 | 
				
			||||||
 | 
					                            select._tables[0].Parameter = (callExp.Arguments[1] as LambdaExpression)?.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                            LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					                            select.OrderByReflection(callExp.Arguments[1] as LambdaExpression as LambdaExpression, false);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case "OrderByDescending":
 | 
				
			||||||
 | 
					                            select._tables[0].Parameter = (callExp.Arguments[1] as LambdaExpression)?.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                            LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					                            select.OrderByReflection(callExp.Arguments[1] as LambdaExpression as LambdaExpression, true);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case "ThenBy":
 | 
				
			||||||
 | 
					                            select._tables[0].Parameter = (callExp.Arguments[1] as LambdaExpression)?.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                            LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					                            select.OrderByReflection(callExp.Arguments[1] as LambdaExpression as LambdaExpression, false);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case "ThenByDescending":
 | 
				
			||||||
 | 
					                            select._tables[0].Parameter = (callExp.Arguments[1] as LambdaExpression)?.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                            LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					                            select.OrderByReflection(callExp.Arguments[1] as LambdaExpression as LambdaExpression, true);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case "Where":
 | 
				
			||||||
 | 
					                            var whereParam = callExp.Arguments[1] as LambdaExpression;
 | 
				
			||||||
 | 
					                            if (whereParam?.Parameters.Count == 1)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                select._tables[0].Parameter = whereParam.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                                LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					                                select.InternalWhere(whereParam);
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            throw throwCallExp(" 不支持");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case "Skip":
 | 
				
			||||||
 | 
					                            select.Offset((int)callExp.Arguments[1].GetConstExprValue());
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case "Take":
 | 
				
			||||||
 | 
					                            select.Limit((int)callExp.Arguments[1].GetConstExprValue());
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        case "Select":
 | 
				
			||||||
 | 
					                            var selectParam = callExp.Arguments[1] as LambdaExpression;
 | 
				
			||||||
 | 
					                            if (selectParam?.Parameters.Count == 1)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                select._tables[0].Parameter = selectParam.Parameters.FirstOrDefault();
 | 
				
			||||||
 | 
					                                LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
 | 
				
			||||||
 | 
					                                select._selectExpression = selectParam;
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            throw throwCallExp(" 不支持");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Exception throwCallExp(string message) => new Exception($"解析失败 {callExp.Method.Name} {message}");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,6 +41,7 @@ namespace FreeSql.Internal
 | 
				
			|||||||
            if (common.CodeFirst.GetDbInfo(entity) != null) return null;
 | 
					            if (common.CodeFirst.GetDbInfo(entity) != null) return null;
 | 
				
			||||||
            if (typeof(IEnumerable).IsAssignableFrom(entity) && entity.IsGenericType == true) return null;
 | 
					            if (typeof(IEnumerable).IsAssignableFrom(entity) && entity.IsGenericType == true) return null;
 | 
				
			||||||
            if (entity.IsArray) return null;
 | 
					            if (entity.IsArray) return null;
 | 
				
			||||||
 | 
					            if (entity.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            object entityDefault = null;
 | 
					            object entityDefault = null;
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -99,7 +99,7 @@ fsql.Select<Tag>().IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name =
 | 
				
			|||||||
//ManyToMany
 | 
					//ManyToMany
 | 
				
			||||||
fsql.Select<Song>()
 | 
					fsql.Select<Song>()
 | 
				
			||||||
  .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "foo"))
 | 
					  .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "foo"))
 | 
				
			||||||
  .Where(s => s.Tags.AsSelect().Any(t => t.Name == "Chinese"))
 | 
					  .Where(s => s.Tags.Any(t => t.Name == "Chinese"))
 | 
				
			||||||
  .ToList();
 | 
					  .ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//Other
 | 
					//Other
 | 
				
			||||||
@@ -107,7 +107,7 @@ fsql.Select<YourType>()
 | 
				
			|||||||
  .Where(a => a.IsDelete == 0)
 | 
					  .Where(a => a.IsDelete == 0)
 | 
				
			||||||
  .WhereIf(keyword != null, a => a.UserName.Contains(keyword))
 | 
					  .WhereIf(keyword != null, a => a.UserName.Contains(keyword))
 | 
				
			||||||
  .WhereIf(role_id > 0, a => a.RoleId == role_id)
 | 
					  .WhereIf(role_id > 0, a => a.RoleId == role_id)
 | 
				
			||||||
  .Where(a => a.Nodes.AsSelect().Any(t => t.Parent.Id == t.UserId))
 | 
					  .Where(a => a.Nodes.Any(t => t.Parent.Id == t.UserId))
 | 
				
			||||||
  .Count(out var total)
 | 
					  .Count(out var total)
 | 
				
			||||||
  .Page(page, size)
 | 
					  .Page(page, size)
 | 
				
			||||||
  .OrderByDescending(a => a.Id)
 | 
					  .OrderByDescending(a => a.Id)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -102,7 +102,7 @@ fsql.Select<Tag>().IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name =
 | 
				
			|||||||
//ManyToMany
 | 
					//ManyToMany
 | 
				
			||||||
fsql.Select<Song>()
 | 
					fsql.Select<Song>()
 | 
				
			||||||
  .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "foo"))
 | 
					  .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "foo"))
 | 
				
			||||||
  .Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语"))
 | 
					  .Where(s => s.Tags.Any(t => t.Name == "国语"))
 | 
				
			||||||
  .ToList();
 | 
					  .ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//Other
 | 
					//Other
 | 
				
			||||||
@@ -110,7 +110,7 @@ fsql.Select<YourType>()
 | 
				
			|||||||
  .Where(a => a.IsDelete == 0)
 | 
					  .Where(a => a.IsDelete == 0)
 | 
				
			||||||
  .WhereIf(keyword != null, a => a.UserName.Contains(keyword))
 | 
					  .WhereIf(keyword != null, a => a.UserName.Contains(keyword))
 | 
				
			||||||
  .WhereIf(role_id > 0, a => a.RoleId == role_id)
 | 
					  .WhereIf(role_id > 0, a => a.RoleId == role_id)
 | 
				
			||||||
  .Where(a => a.Nodes.AsSelect().Any(t => t.Parent.Id == t.UserId))
 | 
					  .Where(a => a.Nodes.Any(t => t.Parent.Id == t.UserId))
 | 
				
			||||||
  .Count(out var total)
 | 
					  .Count(out var total)
 | 
				
			||||||
  .Page(page, size)
 | 
					  .Page(page, size)
 | 
				
			||||||
  .OrderByDescending(a => a.Id)
 | 
					  .OrderByDescending(a => a.Id)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user