联表更新不支持联Queryable 返回

SqlSugar 沟通中
3 126
该叫什么 taoran 发布于1周前
悬赏:0 飞吻

需要的sql大概是:

// UPDATE a 
// SET a.DetailsNum = dc.Cnt
// FROM AirAllocate a
//     INNER JOIN (
//     SELECT AllocateId, COUNT(1) AS Cnt
// FROM AirAllocateDetails
// WHERE AllocateId = @Id
// GROUP BY AllocateId
//     ) dc ON a.Id = dc.AllocateId
// WHERE a.Id = @Id
// AND a.DetailsNum != dc.Cnt;

sqlsugar:

=> => => => => =>

得到了一个错误的sql:

{"sql":"SELECT [No],[Status],[Date],[ArrivalDate],[Destination],[FlightBillNo],[AirLineId],[FlightNo],[FlightDate],[OriginCity],[DestinationCity],[OriginAirportId],[DestinationAirportId],[ScheduledDepartureTime],[ActuallyDepartureTime],[ScheduledArrivalTime],[ActuallyArrivalTime],[Shipper],[ShipperTel],[ShipperArea],[ShipperAddress],[Consignee],[ConsigneeTel],[ConsigneeArea],[ConsigneeAddress],[ReceivingType],[FirstCarrier],[CarrierId],[CarrierName],[CarrierPhone],[CarrierNo],[GoodsType],[GoodsDesc],[Package],[Quantity],[Weight],[Volume],[Size],[CalculateWeight],[InsurancePrice],[FeeRemark],[MovingGroup],[PayType],[SplitType],[Bargain],[DetailsNum],[Void],[VoidRemark],[Voider],[VoidDate],[BookingNo],[Consignor],[ConsignorTel],[ConsignorArea],[ConsignorAddress],[SecondAirportId],[SecondAirLineId],[SecondFlightNo],[SecondFlightDate],[SecondTransferType],[ThirdAirportId],[ThirdAirLineId],[ThirdFlightNo],[ThirdFlightDate],[ThirdTransferType],[CabinClass],[GoodsCode],[OpCode],[HZOpCode],[HZGoodsCode],[BillingRemark],[TransportConditionCertificate],[BatteryDeclaration],[BookingRemark],[StorageTransRemark],[SourceType],[GenerateSubOrder],[Remark],[Id],[Ver],[CreatedBy],[CreatedTime],[UpdatedBy],[UpdatedTime],[IsValid],[IsDeleted],[OrgId] FROM [a]  WHERE   ([AllocateId] IN (0))   AND NOT ( [IsDeleted]=1 ) GROUP BY [AllocateId] )   [d] ON ( [a].[Id] = [d].[AllocateId] ) \r\n WHERE (([a].[Id] IN (0)) AND( [a].[DetailsNum] \u003C\u003E [d].[Count] )) ","parametres":[{"isRefCursor":false,"isClob":false,"isNClob":false,"isNvarchar2":false,"dbType":"Int64","direction":"Input","isNullable":false,"parameterName":"@Id","scale":0,"size":4000,"sourceColumn":null,"sourceColumnNullMapping":false,"udtTypeName":null,"value":0,"tempDate":null,"sourceVersion":0,"typeName":null,"isJson":false,"isArray":false,"customDbType":null,"precision":0}],"targetSite":null,"message":"\u201C)\u201D\u9644\u8FD1\u6709\u8BED\u6CD5\u9519\u8BEF\u3002","data":{},"innerException":null,"helpLink":null,"source":null,"hResult":-2146233088,"stackTrace":null}

报错信息是:“)”附近有语法错误。



纯查询时没有问题,能得到正确的预期的sql语句:

Query()
   .InnerJoin(detailsQuery, (a, d) => a.Id == d.AllocateId)
   .Where((a, d) => ids.Contains(a.Id) && a.DetailsNum != d.Count).ToListAsync();

得到了:

SELECT

  [a].[No],

  [a].[Status],

  [a].[Date],

  [a].[ArrivalDate],

  [a].[Destination],

  [a].[FlightBillNo],

  [a].[AirLineId],

  [a].[DetailsNum],

FROM

  [T_D_AirAllocate] [a]

  INNER JOIN (

  SELECT

    [AllocateId] AS [AllocateId],

    COUNT ( [Id] ) AS [Count] 

  FROM

    [T_D_AirAllocateDetails] 

  WHERE

    ( [AllocateId] IN ( 0 ) ) 

    AND NOT ( [IsDeleted] = 1 ) 

  GROUP BY

    [AllocateId] 

  ) [d] ON ( [a].[Id] = [d].[AllocateId] ) 

WHERE

  ( ( [a].[Id] IN ( 0 ) ) AND ( [a].[DetailsNum] <> [d].[Count] ) ) 

  AND NOT ( [a].[IsDeleted] = 1 )


热忱回答3

  • sqlserver升级最新,还有问题 删掉OBJ和BIN打包上传一个DEMO

    0 回复
  • @fate sta:生成出了错误的sql,应该暂时和sqlserver版本无关。通过写demo我发现问题了,是因为开了EnableDiffLogEvent。

    导致在更新前查源数据时生成出了错误的查询sql。

    所以是因为联表更新不支持difflog 亦或是有bug?


    控制台输出:

    [Sql]:SELECT [Id],[Name],[StudentCount] FROM [a]  WHERE   ([SchoolId] IN (1,2,3)) GROUP BY [SchoolId] )   [d] ON ( [a].[Id] = [d].[SchoolId] )

     WHERE (([a].[Id] IN (1,2,3)) AND( [a].[StudentCount] <> [d].[Count] ))

    [Pars]:

    [Name]:@Id [Value]:0 [Type]:Int32    


    Unhandled exception. Microsoft.Data.SqlClient.SqlException (0x80131904): “)”附近有语法错误。


    DEMO(改自 3秒入门demo):

    using SqlSugar;



    //创建数据库对象 (用法和EF Dappper一样通过new保证线程安全)

    SqlSugarClient Db = new SqlSugarClient(new ConnectionConfig()

    {

        ConnectionString = "Persist Security Info=False;Data Source=127.0.0.1,1433;User ID=sa;Password=123456789;Initial Catalog=TEST;TrustServerCertificate=true;",

        DbType = DbType.SqlServer,

        IsAutoCloseConnection = true

    },

    db =>

    {


        db.Aop.OnLogExecuting = (sql, pars) =>

        {


            //获取原生SQL推荐 5.1.4.63  性能OK

            Console.WriteLine(UtilMethods.GetNativeSql(sql, pars));


            //获取无参数化SQL 对性能有影响,特别大的SQL参数多的,调试使用

            //Console.WriteLine(UtilMethods.GetSqlString(DbType.SqlServer,sql,pars))



        };


        //注意多租户 有几个设置几个

        //db.GetConnection(i).Aop


    });


    //建库

    // Db.DbMaintenance.CreateDatabase();//达梦和Oracle不支持建库


    //建表(看文档迁移)

    // Db.CodeFirst.InitTables<Student>(); //所有库都支持

    // Db.CodeFirst.InitTables<School>(); //所有库都支持


    var ids = new List<int> { 1, 2, 3 };


    // 联表更新

    var detailsQuery = Db.Queryable<Student>()

        .Where(d => ids.Contains(d.SchoolId))

        .GroupBy(d => d.SchoolId)

        .Select(d => new

        {

            d.SchoolId,

            Count = SqlFunc.AggregateCount(d.Id)

        });


    Db.Updateable<School>().EnableDiffLogEvent()

    .InnerJoin(detailsQuery, (a, d) => a.Id == d.SchoolId)

    .SetColumns((a, d) => new School { StudentCount = d.Count })

        .Where((a, d) => ids.Contains(a.Id) && a.StudentCount != d.Count)

        .ExecuteCommand();



    Console.WriteLine("恭喜你已经入门了,后面只需要用到什么查文档就可以了。");

    Console.ReadKey();



    //实体与数据库结构一样

    public class Student

    {

        //数据是自增需要加上IsIdentity

        //数据库是主键需要加上IsPrimaryKey

        //注意:要完全和数据库一致2个属性

        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]

        public int Id { get; set; }

        public int SchoolId { get; set; }

        public string? Name { get; set; }

    }


    public class School

    {

        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]

        public int Id { get; set; }

        public string? Name { get; set; }


        public int StudentCount { get; set; }

    }


    0 回复
  • @fate sta:提供demo了,麻烦看一下

    0 回复