dotnetcore / FreeSql

🦄 .NET aot orm, C# orm, VB.NET orm, Mysql orm, Postgresql orm, SqlServer orm, Oracle orm, Sqlite orm, Firebird orm, 达梦 orm, 人大金仓 orm, 神通 orm, 翰高 orm, 南大通用 orm, 虚谷 orm, 国产 orm, Clickhouse orm, QuestDB orm, MsAccess orm.
http://freesql.net
MIT License
3.99k stars 842 forks source link

参数化异常 UseGenerateCommandParameterWithLambda(true) #1777

Closed zhujiancc closed 1 month ago

zhujiancc commented 1 month ago

demo 代码 【PostgreSQLCodeFirstTest】

 [Fact]
public void 参数化有问题()
{

    g.pgsql.Delete<Roles>().Where(s=>true).ExecuteAffrows();
    var roleList = new List<Roles>
    {
        new Roles()
        {
            Name = "默认",
            CompanyId = 0,
            Type=RoleType.ALl
        },
        new Roles()
        {
            Name = "A",
            CompanyId = 1,
            TeamId = 2,
            Type=RoleType.Team
        },
        new Roles()
        {
            Name = "B",
            CompanyId = 1,
            TeamId = 2,
            Type=RoleType.Team
        },
    };

    g.pgsql.Insert(roleList).ExecuteAffrows();

    var defualtRoles = g.pgsql.Select<Roles>()
        .Where(s => s.CompanyId == 0)
        .Where(s=>s.Type==RoleType.ALl);

    var filter = new { CompanyId = 1, TeamId = 2, PageIndex = 1, PageSize = 10 };

    var data = g.pgsql.Select<Roles>()
        .WhereIf(filter.CompanyId > 0, s => s.CompanyId == filter.CompanyId)
        .WhereIf(filter.TeamId > 0, s => s.TeamId == filter.TeamId)
        .UnionAll(defualtRoles)
        .Count(out var _)
        .OrderBy(s => s.CompanyId)
        .OrderBy(s => s.Id)
        .Page(filter.PageIndex, filter.PageSize)
        .ToList<Roles>();

    _testOutputHelper.WriteLine(data.Count.ToString());
}

public class Roles
{
    [Column(IsIdentity = true, IsPrimary = true)] public Int32 Id { get; set; }

    public String Name { get; set; }

    public int CompanyId { get; set; }

    public int TeamId { get; set; }

    public RoleType Type { get; set; }

}
public enum  RoleType
{
    ALl=10,
    Team=20,
    User=30
}

生成的sql

SELECT a."id", a."name", a."companyid", a."teamid", a."type" 
FROM ( SELECT a."id", a."name", a."companyid", a."teamid", a."type" 
    FROM "roles" a 
    WHERE (a."companyid" = @exp_0) AND (a."teamid" = @exp_1) 
    UNION ALL 
    SELECT a."id", a."name", a."companyid", a."teamid", a."type" 
    FROM "roles" a 
    WHERE (a."companyid" = 0) AND (a."type" = @exp_0) ) a 
ORDER BY a."companyid", a."id" 
limit 10

下面的这个sql ,type 不应该参数化, 逻辑也有点问题 FROM "roles" a WHERE (a."companyid" = 0) AND (a."type" = @exp_0) ) a

数据库版本

all

安装的Nuget包

3.2.813

.net framework/. net core? 及具体版本

net 6

zhujiancc commented 1 month ago

这个问题 有计划 修复吗

2881099 commented 1 month ago

https://freesql.net/guide/unionall.html#withparameters-%E5%8F%82%E6%95%B0%E5%8C%96%E5%85%B1%E4%BA%AB

开启参数化查询功能后,使用 WithParameters 共享参数化,避免产生相同的参数名称:

zhujiancc commented 1 month ago

thx