Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将Func用作select与内联select时sql之间的差异_C#_Sql_Linq_Entity Framework - Fatal编程技术网

C# 将Func用作select与内联select时sql之间的差异

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],

我试图理解为什么这两条语句的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], 
[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);此链接提供有关表达式的更多详细信息,可能会有所帮助: