I recently got a "The mapping of interface member ..... is not supported" error, which I resolved based on this thread. To demonstrate:
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;}
}
and
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);
}
}
Running this code, I'd get a NotSupportedException: "The mapping of interface member IMyInterface.valueText is not supported". However, if I replace the x.valueText == value
with x.valueText.Equals(value)
, this works entirely as expected.
I've solved this in my code, but I want to understand why it behaves this way. Can anyone explain it?
Update: As per my comment below, the LINQ to SQL team closed this as a "Won't fix". I think that means it now counts as a known bug, but one that isn't going to be resolved any time soon. I'd still like to know why it behaves differently in the first place, though.
Apparently the decision to push the query upstream to the server is made based on an incomplete set of rules, and then LINQ-to-SQL finds a construct (an interface) that it can't deal with.
The method call isn't supported by LINQ-to-SQL, so it generates a query to retrieve all records and then uses LINQ-to-Objects to filter them. (Actually, based on your other thread, LINQ-to-SQL may make a special exception for object.Equals
and knows how to convert that to SQL).
LINQ-to-SQL probably should fall back to the LINQ-to-Objects behavior when an interface is involved, but apparently it just throws an exception instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With