这真让我感到困惑.我知道LINQ-to-SQL处理选择是通过处理表达式树并尝试通过生成的查询翻译东西,这就是为什么某些函数转换不起作用属性(string.IsNullOrWhitespace是一个常规的烦恼).我遇到了我的代码中的情况,其中L...
这真让我感到困惑.我知道LINQ-to-SQL处理选择是通过处理表达式树并尝试通过生成的查询翻译东西,这就是为什么某些函数转换不起作用属性(string.IsNullOrWhitespace是一个常规的烦恼).
我遇到了我的代码中的情况,其中LINQ-to-SQL能够通过Select投影调用我的帮助函数…有时候.实际上,当方法有一个名称但它不起作用时它有另一个名称.我认为这可以通过以下程序得到最好的说明(这就像我可以做到的那样简单):
// #define BREAK_THE_CODE
using System;
using Sandbox.Data;
using System.Collections.Generic;
using System.Linq;
namespace Sandbox.Console
{
class Program
{
static void Main(string[] args)
{
using (var dataContext = new SandboxDataContext())
{
List<MyValue> myValueList;
try
{
myValueList = dataContext.Numbers.Select(x => new MyValue
{
#if BREAK_THE_CODE
Type = ToValueType(x.Value),
#else
Type = DoIt(x.Value),
#endif
}).ToList();
}
catch (NotSupportedException)
{
System.Console.WriteLine("Not supported, oh noes!");
System.Console.ReadKey();
return;
}
System.Console.WriteLine(myValueList.Count);
System.Console.ReadKey();
}
}
#if BREAK_THE_CODE
public static MyValueType ToValueType(int value)
#else
public static MyValueType DoIt(int value)
#endif
{
return MyValueType.One;
}
public sealed class MyValue
{
public MyValueType Type { get; set; }
}
public enum MyValueType
{
One,
Two,
Unknown,
}
}
}
后备数据库只有一个名为[Number]的表,其中包含一列[Value] INT NOT NULL.
如上所述,该程序适用于我,但取消注释顶部的#define将切换方法调用的名称,然后程序将在执行ToList()时抛出NotSupportedException.
我已经尝试了几种不同的方法名称来尝试确定一种模式,但却无法做到.看起来如果该方法被命名为以To开头的任何东西,它将抛出NotSupportedException,但似乎与任何其他名称一起使用.这仍然很奇怪.
有人可以解释发生了什么吗?
这是另一个没有#define切换的示例,它只是两种方法背靠背,我仍然看到同样的问题.具体来说,DoIt可以工作,但ToValueType没有.
using System;
using Sandbox.Data;
using System.Linq;
namespace Sandbox.Console
{
class Program
{
static void Main(string[] args)
{
using (var dataContext = new SandboxDataContext())
{
try
{
var myValueList = dataContext.Numbers.Select(x => new MyValue
{
Type = DoIt(x.Value),
}).ToList();
System.Console.WriteLine("DoIt Succeeded, found {0} results", myValueList.Count);
}
catch (NotSupportedException)
{
System.Console.WriteLine("DoIt Failed, oh noes!");
}
try
{
var myValueList = dataContext.Numbers.Select(x => new MyValue
{
Type = ToValueType(x.Value),
}).ToList();
System.Console.WriteLine("ToValueType Succeeded, found {0} results", myValueList.Count);
}
catch (NotSupportedException)
{
System.Console.WriteLine("ToValueType Failed, oh noes!");
}
System.Console.ReadKey();
}
}
public static MyValueType DoIt(int value)
{
return MyValueType.SpecialType;
}
public static MyValueType ToValueType(int value)
{
return MyValueType.SpecialType;
}
public sealed class MyValue
{
public MyValueType Type { get; set; }
}
public enum MyValueType
{
SpecialType,
}
}
}
解决方法:
这是一个L2S错误.预计这将有效.
在反编译的源代码中,我发现:
private static MethodSupport GetDecimalMethodSupport(SqlMethodCall mc)
{
if (mc.Method.IsStatic)
{
if (mc.Arguments.Count == 2)
{
string str;
if (((str = mc.Method.Name) != null) && ((((str == "Multiply") || (str == "Divide")) || ((str == "Subtract") || (str == "Add"))) || ((str == "Remainder") || (str == "Round"))))
{
return MethodSupport.Method;
}
}
else if (mc.Arguments.Count == 1)
{
string str2;
if (((str2 = mc.Method.Name) != null) && (((str2 == "Negate") || (str2 == "Floor")) || ((str2 == "Truncate") || (str2 == "Round"))))
{
return MethodSupport.Method;
}
if (mc.Method.Name.StartsWith("To", StringComparison.Ordinal))
{
return MethodSupport.Method;
}
}
}
return MethodSupport.None;
}
搜索“收件人”:
if (mc.Method.Name.StartsWith("To", StringComparison.Ordinal))
嗯……还有一个地方.也许L2S认为你的价值类型是小数.尝试添加第二个参数以打破mc.Arguments.Count == 1条件.
无论如何,这是一个错误.这背后没有更深层的原因.通常,L2S可以在最终的Select中执行函数.这是EF仍然缺乏的一个很棒的功能.
将其放置休息并尽快迁移到EF. L2S被放弃了.
本文标题为:c# – 为什么LINQ-to-SQL有时允许我使用函数进行投影,但有时它不会?
基础教程推荐
- C#操作配置文件app.config、web.config增删改 2023-06-08
- C#如何获取枚举的描述属性详解 2023-01-11
- C# 读取 appconfig文件配置数据库连接字符串,和配置文件 2023-11-25
- VS2019配置OpenCV4.1.0详细教程与测试代码(推荐) 2023-02-09
- c# – 在此代码中返回相同结果但不同SQL的LINQ方法的执行顺序.到底是怎么回事? 2023-11-23
- C# Winform自动更新程序实例详解 2022-11-27
- C#线程间通信的异步机制 2023-06-09
- C#集合本质之链表的用法详解 2023-06-28
- C#实现装饰器模式 2023-06-21
- 如何在Windows应用商店(WinRT)应用程序中使用C#检查CapsLock按钮的状态 2023-09-20