我有这个函数来计算一组行的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;
}
我需要一杯啤酒!