C# 带有接口和LINQ的==和.Equals()之间的差异

C# 带有接口和LINQ的==和.Equals()之间的差异,c#,linq-to-sql,C#,Linq To Sql,我最近收到一个“接口成员的映射…不受支持”错误,我根据该错误进行了解决。证明: public interface IMyInterface { string valueText { get; set; } } public class MyData : IMyInterface { int ID { get; set;} string valueText { get; set;} } public class MyOtherData : IMyInterface { long

我最近收到一个“接口成员的映射…不受支持”错误,我根据该错误进行了解决。证明:

public interface IMyInterface { string valueText { get; set; } }
public class MyData : IMyInterface
{
   int ID { get; set;}
   string valueText { get; set;}
}
public class MyOtherData : IMyInterface
{
   long ID { get; set;}
   string valueText { get; set;}
}

公共静态IEnumerable GetByValue(字符串值):其中T:class,IMyInterface,new()
{ 
使用(var context=new DataContext())
{ 
//主线
返回context.GetTable(),其中(x=>x.valueText==value);
}
}
运行这段代码,我会得到一个NotSupportedException:“接口成员IMyInterface.valueText的映射不受支持”。但是,如果我将
x.valueText==value
替换为
x.valueText.Equals(value)
,这将完全按照预期工作

我已经在我的代码中解决了这个问题,但我想了解它为什么会这样。有人能解释一下吗


更新:根据我下面的评论,LINQ to SQL团队以“不会修复”结束了此操作。我认为这意味着它现在算是一个已知的bug,但它不会很快得到解决。不过,我还是想知道为什么它的行为会有所不同。

显然,将查询推送到服务器上游的决定是基于一组不完整的规则做出的,然后LINQ to SQL找到了一个它无法处理的构造(接口)

LINQtoSQL不支持该方法调用,因此它会生成一个查询来检索所有记录,然后使用LINQtoObject对其进行筛选。(实际上,根据您的另一个线程,LINQ to SQL可能会对
对象做一个特殊的例外。Equals
,并且知道如何将其转换为SQL)


当涉及到接口时,LINQtoSQL可能应该回到LINQtoObjects行为,但显然它只是抛出一个异常。

哦,我更喜欢异常。如果发现它正在下载表中的内容以在内存中过滤,可能会让我放弃编程并加入马戏团。如果链接线程上的公认答案可信,那么您的猜测是错误的。Linq to SQL似乎为
=
比较和
.Equals
调用生成了相同的正确SQL(包括筛选器的
WHERE
子句),但是为
=
比较抛出了一个异常。@Ben,但是为什么
=
.Equals()之间的行为不同呢
?据我所知,它们在幕后都是一样的,正如@phoog所指出的,它们生成相同的SQL。在阅读了链接到的线程后,我会说这看起来像个bug。@phoog,我也会假设一个bug,只是有一个显式错误。这意味着必须有一些东西来检查这种情况。它可能是一个“忘记添加逻辑”类型的错误,或者是一个为避免错误而编码的异常,但就其本身而言,我认为异常是“正确”的行为。@Bobson,您是否检查了连接以查看是否有人报告过该错误?链接线程中有几个人谈到了这件事,但似乎没有人有足够的主动权自己去做。@phoog,据我所知,还没有人报告过这件事。我刚刚提交的@好的,我也听到了。“感谢您对LINQ to SQL的反馈。我们已经审查了该问题,但目前决定在下一版本的.NET Framework中不采用对LINQ to SQL的更改。”他们将其标记为“不会修复”。
public static IEnumerable<T> GetByValue<T>(string value) : where T : class, IMyInterface, new()
{ 
   using (var context = new DataContext())
   { 
      // The important line
      return context.GetTable<T>().Where(x => x.valueText == value);
   }
}