C# 将Func用作select与内联select时sql之间的差异
我试图理解为什么这两条语句的sql不同(区别似乎在于决定是在select语句中添加SignedXml还是在use case语句中添加SignedXml。但是为什么呢?) 这会产生如下结果:C# 将Func用作select与内联select时sql之间的差异,c#,sql,linq,entity-framework,C#,Sql,Linq,Entity Framework,我试图理解为什么这两条语句的sql不同(区别似乎在于决定是在select语句中添加SignedXml还是在use case语句中添加SignedXml。但是为什么呢?) 这会产生如下结果: exec sp_executesql N'SELECT [Extent1].[ID] AS [ID], [Extent1].[Name] AS [Name], [Extent1].[Created] AS [Created], [Extent1].[FolderID] AS [FolderID],
exec sp_executesql N'SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
[Extent1].[Created] AS [Created],
[Extent1].[FolderID] AS [FolderID],
[Extent1].[Locked] AS [Locked],
[Extent1].[Modified] AS [Modified],
[Extent1].[OwnerID] AS [OwnerID],
CASE WHEN ([Extent1].[SignedXml] IS NOT NULL) THEN cast(1 as bit) WHEN ([Extent1].[SignedXml] IS NULL) THEN cast(0 as bit) END AS [C1]
FROM [dbo].[NativeAnalyses] AS [Extent1]
WHERE ([Extent1].[OwnerID] = @p__linq__0) AND ([Extent1].[FolderID] = @p__linq__1)',N'@p__linq__0 uniqueidentifier,@p__linq__1
exec sp_executesql N'SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
[Extent1].[ModelXml] AS [ModelXml],
[Extent1].[Created] AS [Created],
[Extent1].[Modified] AS [Modified],
[Extent1].[OwnerID] AS [OwnerID],
[Extent1].[SignedXml] AS [SignedXml],
[Extent1].[FolderID] AS [FolderID],
[Extent1].[Locked] AS [Locked]
FROM [dbo].[NativeAnalyses] AS [Extent1]
WHERE ([Extent1].[OwnerID] = @p__linq__0) AND ([Extent1].[FolderID] = @p__linq__1)',N'@p__linq__0 uniqueidentifier,@p__linq__1
vs当我使用功能进行选择时:
myTable.Where(p => p.OwnerID.Equals(owner) && p.FolderID == folderId)
.Select(Select);
选择是
private SignedNativeAnalysis Select(NativeAnalysis source)
{
return new SignedNativeAnalysis
{
ID = source.ID,
Name = source.Name,
Created = source.Created,
FolderID = source.FolderID,
Locked = source.Locked,
Modified = source.Modified,
OwnerID = source.OwnerID,
IsSigned = source.SignedXml != null
};
}
这会产生如下结果:
exec sp_executesql N'SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
[Extent1].[Created] AS [Created],
[Extent1].[FolderID] AS [FolderID],
[Extent1].[Locked] AS [Locked],
[Extent1].[Modified] AS [Modified],
[Extent1].[OwnerID] AS [OwnerID],
CASE WHEN ([Extent1].[SignedXml] IS NOT NULL) THEN cast(1 as bit) WHEN ([Extent1].[SignedXml] IS NULL) THEN cast(0 as bit) END AS [C1]
FROM [dbo].[NativeAnalyses] AS [Extent1]
WHERE ([Extent1].[OwnerID] = @p__linq__0) AND ([Extent1].[FolderID] = @p__linq__1)',N'@p__linq__0 uniqueidentifier,@p__linq__1
exec sp_executesql N'SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
[Extent1].[ModelXml] AS [ModelXml],
[Extent1].[Created] AS [Created],
[Extent1].[Modified] AS [Modified],
[Extent1].[OwnerID] AS [OwnerID],
[Extent1].[SignedXml] AS [SignedXml],
[Extent1].[FolderID] AS [FolderID],
[Extent1].[Locked] AS [Locked]
FROM [dbo].[NativeAnalyses] AS [Extent1]
WHERE ([Extent1].[OwnerID] = @p__linq__0) AND ([Extent1].[FolderID] = @p__linq__1)',N'@p__linq__0 uniqueidentifier,@p__linq__1
而SignedNativeAnalysis只继承了NativeAnalysis的一个额外属性
internal class SignedNativeAnalysis : NativeAnalysis
{
public bool IsSigned { get; set; }
}
更新:
根据建议,我尝试使用表达式来实现我想要的结果,但我得到了一个异常:
Expression<Func<NativeAnalysis, SignedNativeAnalysis>> signed = p => Select(p);
myTable.Where(p => p.OwnerID.Equals(owner) && p.FolderID == folderId)
.Select(signed)
Expression signed=p=>Select(p);
myTable.Where(p=>p.OwnerID.Equals(owner)和&p.FolderID==FolderID)
.选择(签名)
LINQ to实体无法识别方法的SignedNativeAnalysis
选择(www.EntityFramework.NativeAnalysis)方法,然后
方法无法转换为存储表达式
这是个诡计。实体框架选择不接受Func。它需要一个表达式 因此,当您传递lambda时,编译器将lambda转换为表达式,并将其传递给EF,EF将表达式转换为SQL代码 传递Func时,无法将其转换为表达式。而Enumerable.Select扩展方法——它接受一个普通Func,而不是一个表达式——起作用。因此EF在SQL中执行第一部分,直到Where。然后将结果传递给Linq to对象,该对象在内存中执行投影
您仍然可以执行动态操作,但必须创建表达式的实例,而不是委托。好的,我将其更改为使用表达式,但这不起作用,因为我遇到了“此方法无法转换为表达式”错误?我看到了您编辑的问题。您所做的只是创建“callselect(p)method”表达式。但EF不知道如何将“调用选择(p)”转换为SQL代码。这不是你想要的。您需要的是“p=>newsignednativeanalysis{ID=p.ID,…}”表达式。但这基本上是我的第一个选择,包装在一个表达式中。我想要第二个选项(使用函数),这样我就可以在多个位置使用选择,而不必复制它…?您不能使用编译后的函数。但是您仍然可以将表达式存储在字段/变量/静态中,并在代码中共享它。比如:表达式投影=p=>new。。。;然后使用它myTable.Where(…).Select(projection);此链接提供有关表达式的更多详细信息,可能会有所帮助: