动态Linq使用SqlFunction校验和

时间:2015-11-13 02:29:19

标签: c# linq

我有这个函数来计算一组行的checksumAggregate,这些行本身应该是校验和。不幸的是,如果表没有唯一的INT列,那么checksumAggregate是不够的。我必须使用Checksum才能使用其他列。

我正在使用System.Linq.Dynamic来允许该函数是通用的。

下面的代码引用x.ColumnName.ToString()是我需要替换像“ColumnName”之类的东西,就像我为OrderBy和Where子句所做的那样。 (我会在函数的另一个参数中传递字符串)

由于它使用SQLFunctions,我现在仍然坚持如何做到这一点。遗憾的是这个功能没有“*”。

我真的希望这是有道理的。任何正确方向的指针都将受到赞赏。

    public int calculateChecksum<T>(IQueryable<T> query, string SortColumn, DateTime? TimeStamp, Int64 Offset = 0)
    {
        if (TimeStamp == null) {TimeStamp = new DateTime(1800,1,1);}
        string filterExp = SortColumn + " = @0";
        query = query.Where<T>(filterExp, TimeStamp);
        query = query.OrderBy<T>(SortColumn);
        query = query.Take(varTakeCount);
        int outChecksum = SqlFunctions.ChecksumAggregate(query.Select(x => SqlFunctions.Checksum( x.ColumnName.ToString() )));
        return outChecksum;
    }

编辑:

通过一些调整,我可以让ChecksumAggregate在单个INT列上工作。关闭,但不理想。

        string filterType = typeof(T).FullName.Split('.').LastOrDefault();
        var p = Expression.Parameter(typeof(T), filterType);        
        var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, "tablename.columnname");
        int outChecksum = SqlFunctions.ChecksumAggregate(query.Select((Expression<Func<T, int>>)e));

另外,我试着用这样的东西搞错:

        var checksumMethod = typeof (SqlFunctions).GetMethod("Checksum", new[] {typeof (string), typeof (string)});
        var checksumExpression = Expression.Call(checksumMethod,e1,e1);
        var e2=Expression.Lambda<Func<Int32>>(checksumExpression);
        int outChecksum = SqlFunctions.ChecksumAggregate(query.Select(Expression<Func<T, bool>>)e2));

但是不能让它通过运行时。我得到一个Nullable'1 Int32不能被强制转换为Int32。听起来应该是这样。

编辑2:

虽然这不能回答我原来的问题,但我发现了一个黑客攻击。

    public int calculateChecksum<T, TContext>(DbContext context, IQueryable<T> query, string sortColumn, DateTime? TimeStamp, int Offset = 1)
    {
        if (TimeStamp == null) {TimeStamp = new DateTime(1800,1,1);}
        string filterExp = sortColumn + " = @0";
        query = query.Where<T>(filterExp, TimeStamp);
        query = query.OrderBy<T>(sortColumn);
        query = query.Take(Offset);

        string sql = query.ToString();
        sql = string.Format("select checksum_agg(BC) from ( select binary_checksum(*) as BC from ({0}) b ) c",sql);
        int result = context.Database.SqlQuery<int>(sql).FirstOrDefault();
        return result;
    }

我需要一杯啤酒!

0 个答案:

没有答案