Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.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# 为什么ToString()会如此显著地降低实体框架的性能_C#_Sql Server_Entity Framework_Linq - Fatal编程技术网

C# 为什么ToString()会如此显著地降低实体框架的性能

C# 为什么ToString()会如此显著地降低实体框架的性能,c#,sql-server,entity-framework,linq,C#,Sql Server,Entity Framework,Linq,我有一个简单的LINQ查询,执行8395毫秒: var _context = new SurveyContext(); _context.Database.Log = Console.WriteLine; (from p in _context.Participants join row in _context.ListAnswerSelections on new {p.Id, QuestionId = 434} equals new {Id = row.Rel

我有一个简单的LINQ查询,执行8395毫秒:

var _context = new SurveyContext(); 
_context.Database.Log = Console.WriteLine;
 (from p in _context.Participants
  join row in _context.ListAnswerSelections
      on new {p.Id, QuestionId = 434} equals
      new {Id = row.RelatedParticipantId, QuestionId = row.RelatedQuestionId}
  select new { V = row.NumericValue.ToString() })
  .ToList()
  .Select(x => new {R = x.V})
  .Count()  //This is just to see one number instead of whole result
  .Dump("Results");
其IL:

IL_0000:  nop         
IL_0001:  newobj      Survey.Model.SurveyContext..ctor
IL_0006:  stloc.0     // _context
IL_0007:  ldloc.0     // _context
IL_0008:  callvirt    System.Data.Entity.DbContext.get_Database
IL_000D:  ldnull      
IL_000E:  ldftn       System.Console.WriteLine
IL_0014:  newobj      System.Action<System.String>..ctor
IL_0019:  callvirt    System.Data.Entity.Database.set_Log
IL_001E:  nop         
IL_001F:  ldloc.0     // _context
IL_0020:  callvirt    Survey.Model.SurveyContext.get_Participants
IL_0025:  ldloc.0     // _context
IL_0026:  callvirt    Survey.Model.SurveyContext.get_ListAnswerSelections
IL_002B:  ldtoken     Survey.Model.Participant
IL_0030:  call        System.Type.GetTypeFromHandle
IL_0035:  ldstr       "p"
IL_003A:  call        System.Linq.Expressions.Expression.Parameter
IL_003F:  stloc.1     // CS$0$0000
IL_0040:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>..ctor
IL_0045:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>
IL_004A:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_004F:  castclass   System.Reflection.ConstructorInfo
IL_0054:  ldc.i4.2    
IL_0055:  newarr      System.Linq.Expressions.Expression
IL_005A:  stloc.2     // CS$0$0001
IL_005B:  ldloc.2     // CS$0$0001
IL_005C:  ldc.i4.0    
IL_005D:  ldloc.1     // CS$0$0000
IL_005E:  ldtoken     Survey.Model.ModelBase.get_Id
IL_0063:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_0068:  castclass   System.Reflection.MethodInfo
IL_006D:  call        System.Linq.Expressions.Expression.Property
IL_0072:  stelem.ref  
IL_0073:  ldloc.2     // CS$0$0001
IL_0074:  ldc.i4.1    
IL_0075:  ldc.i4      B2 01 00 00 
IL_007A:  box         System.Int32
IL_007F:  ldtoken     System.Int32
IL_0084:  call        System.Type.GetTypeFromHandle
IL_0089:  call        System.Linq.Expressions.Expression.Constant
IL_008E:  stelem.ref  
IL_008F:  ldloc.2     // CS$0$0001
IL_0090:  ldc.i4.2    
IL_0091:  newarr      System.Reflection.MethodInfo
IL_0096:  stloc.3     // CS$0$0002
IL_0097:  ldloc.3     // CS$0$0002
IL_0098:  ldc.i4.0    
IL_0099:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>.get_Id
IL_009E:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>
IL_00A3:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_00A8:  castclass   System.Reflection.MethodInfo
IL_00AD:  stelem.ref  
IL_00AE:  ldloc.3     // CS$0$0002
IL_00AF:  ldc.i4.1    
IL_00B0:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>.get_QuestionId
IL_00B5:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>
IL_00BA:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_00BF:  castclass   System.Reflection.MethodInfo
IL_00C4:  stelem.ref  
IL_00C5:  ldloc.3     // CS$0$0002
IL_00C6:  call        System.Linq.Expressions.Expression.New
IL_00CB:  ldc.i4.1    
IL_00CC:  newarr      System.Linq.Expressions.ParameterExpression
IL_00D1:  stloc.s     04 // CS$0$0003
IL_00D3:  ldloc.s     04 // CS$0$0003
IL_00D5:  ldc.i4.0    
IL_00D6:  ldloc.1     // CS$0$0000
IL_00D7:  stelem.ref  
IL_00D8:  ldloc.s     04 // CS$0$0003
IL_00DA:  call        System.Linq.Expressions.Expression.Lambda
IL_00DF:  ldtoken     Survey.Model.ListAnswerSelection
IL_00E4:  call        System.Type.GetTypeFromHandle
IL_00E9:  ldstr       "row"
IL_00EE:  call        System.Linq.Expressions.Expression.Parameter
IL_00F3:  stloc.1     // CS$0$0000
IL_00F4:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>..ctor
IL_00F9:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>
IL_00FE:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_0103:  castclass   System.Reflection.ConstructorInfo
IL_0108:  ldc.i4.2    
IL_0109:  newarr      System.Linq.Expressions.Expression
IL_010E:  stloc.2     // CS$0$0001
IL_010F:  ldloc.2     // CS$0$0001
IL_0110:  ldc.i4.0    
IL_0111:  ldloc.1     // CS$0$0000
IL_0112:  ldtoken     Survey.Model.ListAnswerSelection.get_RelatedParticipantId
IL_0117:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_011C:  castclass   System.Reflection.MethodInfo
IL_0121:  call        System.Linq.Expressions.Expression.Property
IL_0126:  stelem.ref  
IL_0127:  ldloc.2     // CS$0$0001
IL_0128:  ldc.i4.1    
IL_0129:  ldloc.1     // CS$0$0000
IL_012A:  ldtoken     Survey.Model.ListAnswerSelection.get_RelatedQuestionId
IL_012F:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_0134:  castclass   System.Reflection.MethodInfo
IL_0139:  call        System.Linq.Expressions.Expression.Property
IL_013E:  stelem.ref  
IL_013F:  ldloc.2     // CS$0$0001
IL_0140:  ldc.i4.2    
IL_0141:  newarr      System.Reflection.MethodInfo
IL_0146:  stloc.3     // CS$0$0002
IL_0147:  ldloc.3     // CS$0$0002
IL_0148:  ldc.i4.0    
IL_0149:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>.get_Id
IL_014E:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>
IL_0153:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_0158:  castclass   System.Reflection.MethodInfo
IL_015D:  stelem.ref  
IL_015E:  ldloc.3     // CS$0$0002
IL_015F:  ldc.i4.1    
IL_0160:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>.get_QuestionId
IL_0165:  ldtoken     <>f__AnonymousType0<System.Int32,System.Int32>
IL_016A:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_016F:  castclass   System.Reflection.MethodInfo
IL_0174:  stelem.ref  
IL_0175:  ldloc.3     // CS$0$0002
IL_0176:  call        System.Linq.Expressions.Expression.New
IL_017B:  ldc.i4.1    
IL_017C:  newarr      System.Linq.Expressions.ParameterExpression
IL_0181:  stloc.s     04 // CS$0$0003
IL_0183:  ldloc.s     04 // CS$0$0003
IL_0185:  ldc.i4.0    
IL_0186:  ldloc.1     // CS$0$0000
IL_0187:  stelem.ref  
IL_0188:  ldloc.s     04 // CS$0$0003
IL_018A:  call        System.Linq.Expressions.Expression.Lambda
IL_018F:  ldtoken     Survey.Model.Participant
IL_0194:  call        System.Type.GetTypeFromHandle
IL_0199:  ldstr       "p"
IL_019E:  call        System.Linq.Expressions.Expression.Parameter
IL_01A3:  stloc.1     // CS$0$0000
IL_01A4:  ldtoken     Survey.Model.ListAnswerSelection
IL_01A9:  call        System.Type.GetTypeFromHandle
IL_01AE:  ldstr       "row"
IL_01B3:  call        System.Linq.Expressions.Expression.Parameter
IL_01B8:  stloc.s     05 // CS$0$0004
IL_01BA:  ldtoken     <>f__AnonymousType1<System.String>..ctor
IL_01BF:  ldtoken     <>f__AnonymousType1<System.String>
IL_01C4:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_01C9:  castclass   System.Reflection.ConstructorInfo
IL_01CE:  ldc.i4.1    
IL_01CF:  newarr      System.Linq.Expressions.Expression
IL_01D4:  stloc.2     // CS$0$0001
IL_01D5:  ldloc.2     // CS$0$0001
IL_01D6:  ldc.i4.0    
IL_01D7:  ldloc.s     05 // CS$0$0004
IL_01D9:  ldtoken     Survey.Model.ListAnswerSelection.get_NumericValue
IL_01DE:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_01E3:  castclass   System.Reflection.MethodInfo
IL_01E8:  call        System.Linq.Expressions.Expression.Property
IL_01ED:  ldtoken     System.Int32.ToString
IL_01F2:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_01F7:  castclass   System.Reflection.MethodInfo
IL_01FC:  ldc.i4.0    
IL_01FD:  newarr      System.Linq.Expressions.Expression
IL_0202:  call        System.Linq.Expressions.Expression.Call
IL_0207:  stelem.ref  
IL_0208:  ldloc.2     // CS$0$0001
IL_0209:  ldc.i4.1    
IL_020A:  newarr      System.Reflection.MethodInfo
IL_020F:  stloc.3     // CS$0$0002
IL_0210:  ldloc.3     // CS$0$0002
IL_0211:  ldc.i4.0    
IL_0212:  ldtoken     <>f__AnonymousType1<System.String>.get_V
IL_0217:  ldtoken     <>f__AnonymousType1<System.String>
IL_021C:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_0221:  castclass   System.Reflection.MethodInfo
IL_0226:  stelem.ref  
IL_0227:  ldloc.3     // CS$0$0002
IL_0228:  call        System.Linq.Expressions.Expression.New
IL_022D:  ldc.i4.2    
IL_022E:  newarr      System.Linq.Expressions.ParameterExpression
IL_0233:  stloc.s     04 // CS$0$0003
IL_0235:  ldloc.s     04 // CS$0$0003
IL_0237:  ldc.i4.0    
IL_0238:  ldloc.1     // CS$0$0000
IL_0239:  stelem.ref  
IL_023A:  ldloc.s     04 // CS$0$0003
IL_023C:  ldc.i4.1    
IL_023D:  ldloc.s     05 // CS$0$0004
IL_023F:  stelem.ref  
IL_0240:  ldloc.s     04 // CS$0$0003
IL_0242:  call        System.Linq.Expressions.Expression.Lambda
IL_0247:  call        System.Linq.Queryable.Join
IL_024C:  call        System.Linq.Enumerable.ToList
IL_0251:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate2
IL_0256:  brtrue.s    IL_026B
IL_0258:  ldnull      
IL_0259:  ldftn       UserQuery.<Main>b__1
IL_025F:  newobj      System.Func<<>f__AnonymousType1<System.String>,<>f__AnonymousType2<System.String>>..ctor
IL_0264:  stsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate2
IL_0269:  br.s        IL_026B
IL_026B:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate2
IL_0270:  call        System.Linq.Enumerable.Select
IL_0275:  call        System.Linq.Enumerable.Count
IL_027A:  ldstr       "Results"
IL_027F:  call        LINQPad.Extensions.Dump
IL_0284:  pop         
IL_0285:  ret         

<Main>b__1:
IL_0000:  ldarg.0     
IL_0001:  callvirt    <>f__AnonymousType1<System.String>.get_V
IL_0006:  newobj      <>f__AnonymousType2<System.String>..ctor
IL_000B:  stloc.0     // CS$1$0000
IL_000C:  br.s        IL_000E
IL_000E:  ldloc.0     // CS$1$0000
IL_000F:  ret         

<>f__AnonymousType1`1.get_V:
IL_0000:  ldarg.0     
IL_0001:  ldfld       16 00 00 0A 
IL_0006:  stloc.0     
IL_0007:  br.s        IL_0009
IL_0009:  ldloc.0     
IL_000A:  ret         

<>f__AnonymousType1`1.ToString:
IL_0000:  newobj      System.Text.StringBuilder..ctor
IL_0005:  stloc.0     
IL_0006:  ldloc.0     
IL_0007:  ldstr       "{ V = "
IL_000C:  callvirt    System.Text.StringBuilder.Append
IL_0011:  pop         
IL_0012:  ldloc.0     
IL_0013:  ldarg.0     
IL_0014:  ldfld       16 00 00 0A 
IL_0019:  box         02 00 00 1B 
IL_001E:  callvirt    System.Text.StringBuilder.Append
IL_0023:  pop         
IL_0024:  ldloc.0     
IL_0025:  ldstr       " }"
IL_002A:  callvirt    System.Text.StringBuilder.Append
IL_002F:  pop         
IL_0030:  ldloc.0     
IL_0031:  callvirt    System.Object.ToString
IL_0036:  stloc.1     
IL_0037:  br.s        IL_0039
IL_0039:  ldloc.1     
IL_003A:  ret         

<>f__AnonymousType1`1.Equals:
IL_0000:  ldarg.1     
IL_0001:  isinst      06 00 00 1B 
IL_0006:  stloc.0     
IL_0007:  ldloc.0     
IL_0008:  brfalse.s   IL_0022
IL_000A:  call        10 00 00 0A 
IL_000F:  ldarg.0     
IL_0010:  ldfld       16 00 00 0A 
IL_0015:  ldloc.0     
IL_0016:  ldfld       16 00 00 0A 
IL_001B:  callvirt    11 00 00 0A 
IL_0020:  br.s        IL_0023
IL_0022:  ldc.i4.0    
IL_0023:  nop         
IL_0024:  stloc.1     
IL_0025:  br.s        IL_0027
IL_0027:  ldloc.1     
IL_0028:  ret         

<>f__AnonymousType1`1.GetHashCode:
IL_0000:  ldc.i4      8B 15 0F EC 
IL_0005:  stloc.0     
IL_0006:  ldc.i4      29 55 55 A5 
IL_000B:  ldloc.0     
IL_000C:  mul         
IL_000D:  call        10 00 00 0A 
IL_0012:  ldarg.0     
IL_0013:  ldfld       16 00 00 0A 
IL_0018:  callvirt    14 00 00 0A 
IL_001D:  add         
IL_001E:  stloc.0     
IL_001F:  ldloc.0     
IL_0020:  stloc.1     
IL_0021:  br.s        IL_0023
IL_0023:  ldloc.1     
IL_0024:  ret         

<>f__AnonymousType1`1..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ldarg.0     
IL_0007:  ldarg.1     
IL_0008:  stfld       16 00 00 0A 
IL_000D:  ret         

<>f__AnonymousType2`1.get_R:
IL_0000:  ldarg.0     
IL_0001:  ldfld       17 00 00 0A 
IL_0006:  stloc.0     
IL_0007:  br.s        IL_0009
IL_0009:  ldloc.0     
IL_000A:  ret         

<>f__AnonymousType2`1.ToString:
IL_0000:  newobj      System.Text.StringBuilder..ctor
IL_0005:  stloc.0     
IL_0006:  ldloc.0     
IL_0007:  ldstr       "{ R = "
IL_000C:  callvirt    System.Text.StringBuilder.Append
IL_0011:  pop         
IL_0012:  ldloc.0     
IL_0013:  ldarg.0     
IL_0014:  ldfld       17 00 00 0A 
IL_0019:  box         02 00 00 1B 
IL_001E:  callvirt    System.Text.StringBuilder.Append
IL_0023:  pop         
IL_0024:  ldloc.0     
IL_0025:  ldstr       " }"
IL_002A:  callvirt    System.Text.StringBuilder.Append
IL_002F:  pop         
IL_0030:  ldloc.0     
IL_0031:  callvirt    System.Object.ToString
IL_0036:  stloc.1     
IL_0037:  br.s        IL_0039
IL_0039:  ldloc.1     
IL_003A:  ret         

<>f__AnonymousType2`1.Equals:
IL_0000:  ldarg.1     
IL_0001:  isinst      07 00 00 1B 
IL_0006:  stloc.0     
IL_0007:  ldloc.0     
IL_0008:  brfalse.s   IL_0022
IL_000A:  call        10 00 00 0A 
IL_000F:  ldarg.0     
IL_0010:  ldfld       17 00 00 0A 
IL_0015:  ldloc.0     
IL_0016:  ldfld       17 00 00 0A 
IL_001B:  callvirt    11 00 00 0A 
IL_0020:  br.s        IL_0023
IL_0022:  ldc.i4.0    
IL_0023:  nop         
IL_0024:  stloc.1     
IL_0025:  br.s        IL_0027
IL_0027:  ldloc.1     
IL_0028:  ret         

<>f__AnonymousType2`1.GetHashCode:
IL_0000:  ldc.i4      21 74 32 1C 
IL_0005:  stloc.0     
IL_0006:  ldc.i4      29 55 55 A5 
IL_000B:  ldloc.0     
IL_000C:  mul         
IL_000D:  call        10 00 00 0A 
IL_0012:  ldarg.0     
IL_0013:  ldfld       17 00 00 0A 
IL_0018:  callvirt    14 00 00 0A 
IL_001D:  add         
IL_001E:  stloc.0     
IL_001F:  ldloc.0     
IL_0020:  stloc.1     
IL_0021:  br.s        IL_0023
IL_0023:  ldloc.1     
IL_0024:  ret         

<>f__AnonymousType2`1..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ldarg.0     
IL_0007:  ldarg.1     
IL_0008:  stfld       17 00 00 0A 
IL_000D:  ret         
实体框架版本=6.1.0.133一直在做什么

对LINQ查询的微小更改,即删除select部分中的ToString调用,使其执行749毫秒:

    var _context = new SurveyContext(); 
_context.Database.Log = Console.WriteLine;
 (from p in _context.Participants
  join row in _context.ListAnswerSelections
      on new {p.Id, QuestionId = 434} equals
      new {Id = row.RelatedParticipantId, QuestionId = row.RelatedQuestionId}
  select new { V = row.NumericValue })
  .ToList()
  .Select(x => new { R = x.V.ToString() })
  .Count()
  .Dump("Results");
使用以下生成的SQL查询:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent2].[NumericValue] AS [NumericValue]
FROM  [dbo].[Participants] AS [Extent1]
INNER JOIN [dbo].[ListAnswerSelections] AS [Extent2] ON ([Extent1].[Id] =  [Extent2].[ListAnswer_RelatedParticipantId]) AND (434 = [Extent2].[ListAnswer_RelatedQuestionId])


-- Executing at 08-Oct-15 3:33:33 PM +03:00

-- Completed in 367 ms with result: SqlDataReader
我可以看到,转换为字符串降低了SQL执行的性能,是原来的1.8倍。但EF的性能下降了11.2倍。为什么会这样?如果我真的需要在查询的select部分使用ToString,如何避免这种性能损失

更新 如果您希望它更快,只需使用强制转换,您可能需要为该查询创建一个视图模型

select new { V = row.NumericValue as string})
而不是

select new { V = row.NumericValue.ToString() })

调用Int32.ToString时,它会从mscorlib调用Number.FormatInt32

但是,FormatInt32是在系统dll中定义的,其源代码是可用的

事情是这样的:

 for (int i = 300000; i >= 0; i--)
            {
                ToString() //Calls Number.FormatInt32 from mscorlib which is defined to an external dll
                {
                    FormatInt32() //From mscorlib: Call an external dll from the system
                    {
                        FormatInt32() //From ComNumber: Determine the type of convertion
                        NumberToString() // Execute the convertion
                    }
                }
            }
老答案 你从那个查询中得到了多少结果

执行SQL查询,然后使用for循环将结果Int转换为字符串。详情如下:

对于每个获取的整数,它都会这样做 其他性能问题 另外,在运行时创建匿名类型而不是声明模型时可能会产生开销


您还可以看到:

看起来延迟实际上是由双转换整数->字符串->整数引入的。我假定域对象上的属性是强类型的整数。当使用.ToString执行Linq查询时,该字段在SQL server上从整数转换为字符串,这会引入一点延迟,正如您在问题中所注意到的。但是,数据实际上是以该字符串格式从SQL返回到EF的。但域对象属性是一个整数,因此EF必须将该字符串转换回整数才能填充该对象。EF必须在每一行上解析该字符串,很可能使用Integer.TryParse,这将产生非常大的影响


我相信,如果将性能分析器连接到应用程序,您会发现它在linq查询中的大部分时间都停留在integer.TryParse中。

因此,我在AdventureWorks上通过LINQPad运行了以下两个表达式来测试一个理论:

from p in Persons
join row in BusinessEntityAddresses
    on new {p.BusinessEntityID}  equals new {row.BusinessEntityID}
select new { V = row.ModifiedDate }

两人都有一些反思:

IL_017D:  ldtoken     <>f__AnonymousType1<System.String>.get_V
IL_0182:  ldtoken     <>f__AnonymousType1<System.String>
IL_0187:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_018C:  castclass   System.Reflection.MethodInfo
似乎在LINQ查询中调用.ToString会给每个条目带来额外的重复反射开销。当您稍后调用它时,编译器知道如何内联反射以更有效地访问.ToString


似乎底线是,您应该避免在LINQ查询中调用方法,因为额外的反射开销GetMethodFromHandle,MethodInfo以您意想不到的方式烘焙到您的查询中。

他知道sql端的转换会增加一些开销,但是延迟他担心.NET和数据库之间的巨大延迟,即296990。我已经做了计算,以确保不会有太多的数据传输影响性能。我在两个例子中都有匿名类型,但性能不同……我应该更清楚第一个链接。对于int x=0;x<迭代次数;x++{s[x]=i[x].ToString;}他知道如何让它运行得更快,他想知道它为什么会这样工作。当你调用Int32.ToString时,它会从mscorlib调用Number.FormatInt32。然而,FormatInt32是在一个系统dll中定义的,它的源代码在这里是可用的。对不起,我不能理解这一点。您的意思是EF必须填充row.NumericValue吗?但是为什么呢?根据查询,唯一需要的是一个匿名对象,它有一个名为V的字符串属性。所有这些字符串都可以从SQL查询中获得…这实际上是正确的,但在你们开始思考这里如何涉及反射之前,对我来说并没有任何意义。你们在哪里看到转换回整数的过程?我看到的只是一个匿名类型的创建,我会尝试在LINQPad中加载它,并设置数据上下文,然后查看生成的IL以获得这两个结果。这应该告诉你幕后到底发生了什么。如果不设置一些可能需要更多时间的实体内容,我无法复制您的结果。完成。长命令列表。我不太擅长阅读IL:-你能为两者添加IL吗?添加了第一个IL,有问题的一个。因此不允许添加更多符号。1。如果你只是想数一数,为什么还要去串呢?2.在这两种情况下,您都可以使用AsEnumerable而不是ToList。您使用的是ToString还是ToString?是什么让你认为每个条目都会发生这种情况?在我看来,它只是在检查表达式树以将其转换为等效的SQL。对不起,在复制过去时输入错误-我确实使用了ToString。反射代码必须在创建的每个实例上运行,即每个结果一个实例。
from p in Persons
join row in BusinessEntityAddresses
    on new {p.BusinessEntityID}  equals new {row.BusinessEntityID}
select new { V = row.ModifiedDate }
from p in Persons
join row in BusinessEntityAddresses
    on new {p.BusinessEntityID}  equals new {row.BusinessEntityID}
select new { V = row.ModifiedDate.ToString() }
IL_017D:  ldtoken     <>f__AnonymousType1<System.String>.get_V
IL_0182:  ldtoken     <>f__AnonymousType1<System.String>
IL_0187:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_018C:  castclass   System.Reflection.MethodInfo
IL_014E:  call        System.Reflection.FieldInfo.GetFieldFromHandle
IL_0153:  call        System.Linq.Expressions.Expression.Field
IL_0158:  ldtoken     System.Object.ToString
IL_015D:  call        System.Reflection.MethodBase.GetMethodFromHandle
IL_0162:  castclass   System.Reflection.MethodInfo
IL_0167:  ldc.i4.0    
IL_0168:  newarr      System.Linq.Expressions.Expression
IL_016D:  call        System.Linq.Expressions.Expression.Call
IL_0172:  stelem.ref  
IL_0173:  ldloc.1     // CS$0$0001
IL_0174:  ldc.i4.1    
IL_0175:  newarr      System.Reflection.MethodInfo
IL_017A:  stloc.2     // CS$0$0002
IL_017B:  ldloc.2     // CS$0$0002
IL_017C:  ldc.i4.0