我们正考虑为ORMBattle.NET添加更多LINQ测试,但没有更多的想法。所有LINQ测试都检查常见的LINQ功能:
目前,LINQ测试序列的目标是自动计算LINQ实现覆盖率。
先决条件:
如果您对可添加的内容有任何想法,请分享。我肯定会接受满足上述要求的任何 LINQ查询示例,并且可能 - 与改进测试套件有关的一些好主意,可以实现(例如,如果你建议我们手动研究翻译的质量,这是行不通的,因为我们不能自动化这个。)
答案 0 :(得分:8)
Expression.Invoke
表示子表达式;适用于LINQ-to-SQL和LINQ-to-Objects,但不适用于3.5SP1中的EF(适用于IEnumerable<T>
,请先调用.AsQueryable()
):
Expression<Func<Customer, bool>> pred1 = cust=>cust.Country=="UK";
Expression<Func<Customer, bool>> pred2 = cust=>cust.Country=="France";
var param = Expression.Parameter(typeof(Customer), "x");
var final = Expression.Lambda<Func<Customer, bool>>(
Expression.OrElse(
Expression.Invoke(pred1, param),
Expression.Invoke(pred2, param)
), param);
using (var ctx = new DataClasses1DataContext())
{
ctx.Log = Console.Out;
int ukPlusFrance = ctx.Customers.Count(final);
}
示例LINQ-to-SQL输出(EF在sparks中爆炸):
SELECT COUNT(*) AS [value]
FROM [dbo].[Customers] AS [t0]
WHERE ([t0].[Country] = @p0) OR ([t0].[Country] = @p1)
-- @p0: Input NVarChar (Size = 2; Prec = 0; Scale = 0) [UK]
-- @p1: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [France]
身份管理员短路,没有往返 - 即
var obj = ctx.Single(x=>x.Id == id);
var obj = ctx.Where(x=>x.Id == id).Single();
如果具有该身份的对象已经实现并存储在身份管理器中,等 也适用于First
,SingleOrDefault
,FirstOrDefault
。请参阅LINQ-to-SQL(也是here和here;您可以通过附加到.Log
)进行验证;例如:
using (var ctx = new DataClasses1DataContext())
{
ctx.Log = Console.Out;
var first = ctx.Customers.First();
string id = first.CustomerID;
Console.WriteLine("Any more trips?");
var firstDup = ctx.Customers.First(x=>x.CustomerID==id);
Console.WriteLine(ReferenceEquals(first, firstDup)); // true
Console.WriteLine("Prove still attached");
int count = ctx.Customers.Count();
}
日志输出仅显示两次行程;一个是第一次获得对象,一个是计数;它还显示了由materializer返回的相同对象引用:
SELECT TOP (1) [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[
ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t
0].[Country], [t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.492
6
Any more trips?
True <==== this is object reference equality, not "are there any more trips"
Prove still attached
SELECT COUNT(*) AS [value]
FROM [dbo].[Customers] AS [t0]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.492
6
UDF支持;一个简单的例子也适用于LINQ到对象:
partial class MyDataContext {
[Function(Name="NEWID", IsComposable=true)]
public Guid Random() { return Guid.NewGuid();}
}
然后按x => ctx.Random()
排序;例如:
using (var ctx = new DataClasses1DataContext())
{
ctx.Log = Console.Out;
var anyAtRandom = (from cust in ctx.Customers
orderby ctx.Random()
select cust).First();
}
带输出:
SELECT TOP (1) [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0]
ORDER BY NEWID()
如果我感觉真的邪恶,recursive lambda;可能不值得以任何方式支持此...同样,4.0表达式(DLR)节点类型。