我看不到解決方案,它解決了所有限制。這是使用ORM映射程序的注意事項之一,您無法控制生成的SQL。
在這種情況下,如果將多個查詢發送到數據庫是完全不可接受的,那麼嚴酷的事實是您必須自己編寫查詢。
更新
我得到了好奇,並創建了一個擴展方法可以做到這一點!當然,它構造了自己的SQL命令,它只適用於Linq2SQL。同時大規模免責聲明:這是相當骯髒的代碼,如果我有時間,我會在週末:)
public static TOut CountMany<TContext, TOut>(this TContext db, Expression<Func<TContext, TOut>> tableSelector)
where TContext: DataContext
{
var newExpression = (NewExpression) tableSelector.Body;
var tables =
newExpression.Arguments.OfType<MethodCallExpression>()
.SelectMany(mce => mce.Arguments.OfType<MemberExpression>())
.ToList();
var command = new string[tables.Count];
for(var i = 0; i < tables.Count; i++)
{
var table = tables[i];
var tableType = ((PropertyInfo) table.Member).PropertyType.GetGenericArguments()[0];
var tableName = tableType.GetCustomAttribute<TableAttribute>().Name;
command[i] = string.Format("(SELECT COUNT(*) FROM {0}) AS T{1}", tableName, i);
}
var dbCommand = db.Connection.CreateCommand();
dbCommand.CommandText = string.Format("SELECT {0}", String.Join(",", command));
db.Connection.Open();
IDataRecord result;
try
{
result = dbCommand.ExecuteReader().OfType<IDataRecord>().First();
}
finally
{
db.Connection.Close();
}
var results = new object[tables.Count];
for (var i = 0; i < tables.Count; i++)
results[i] = result.GetInt32(i);
var ctor = typeof(TOut).GetConstructor(Enumerable.Repeat(typeof(int), tables.Count).ToArray());
return (TOut) ctor.Invoke(results);
}
的代碼被稱爲像這樣解決起來:
var counts = dbContext.CountMany(db => new
{
table1Count = db.Table1.Count(),
table2Count = db.Table2.Count()
//etc.
});
這是爲什麼第一條語句無效? – Magnus
@Magnus我沒有使用任何SQL分析器,但我認爲這是生成兩個「獨立」查詢,而不是我正在尋找的SQL語句。 – Dryadwoods
爲什麼這很重要? – Magnus