C# SQL to Linq语句中的独立子查询(仅命中一次DB)
具有类似于:C# SQL to Linq语句中的独立子查询(仅命中一次DB),c#,.net,linq,entity-framework,ef-code-first,C#,.net,Linq,Entity Framework,Ef Code First,具有类似于: SELECT (SELECT COUNT(*) from Table1),(SELECT COUNT(*) from Table2 ) 我怎么用linq写呢?还是说这很简单,不可能 限制: 只能命中数据库一次: var result = new { Sum1 = db.Table1.Count(), Sum2 = db.Table2.Count() }); // is
SELECT (SELECT COUNT(*) from Table1),(SELECT COUNT(*) from Table2 )
我怎么用linq写呢?还是说这很简单,不可能
限制:
- 只能命中数据库一次:
var result = new { Sum1 = db.Table1.Count(), Sum2 = db.Table2.Count() }); // is not valid.....
- 我不想使用类似的东西(使用“帮助”表):
- 未使用
db.Database.ExecuteSqlCommand
这有什么关系?好吧,也许你应该在问题中包括真正的目的,这样我们才能更准确地帮助你。你在写两个独立的查询。在SQL中使用子查询时,它会独立执行查询并返回结果。如果有一种方法可以在linq中做到这一点而不执行两个查询,我会感到惊讶,有一种方法可以做到这一点,但它的性能非常糟糕。您可以使用外部联接来联接这两个表,并计算不同的ID。。。但如果你这么做了,请做输精管切除术底线是:你不能用LINQ从无到有。我仍然没有尝试过,但乍一看,我会给你(至少)一个投票,仅仅是因为你努力和动机去寻找答案:)谢谢x)我误解了你的问题,认为你在使用Linq2Sql,而不是实体框架,因此,我的代码不会与您的代码无缝集成:/尽管只有tableName和dbCommand的获取应该不同!
var result = (from t3 in db.Table3
select new {
Sum1 = db.Table1.Count(),
Sum2 = db.Table2.Count()
}).firstOrDefault();
//In order to get only the first row
//but it will not return nothing if the table 3 has no entries......
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.
});