Reputation: 3122
I've encountered a strange issue using CompiledQuery.Compile
. When trying to use a static readonly field within a query, I get the following error message:
Class member X is unmapped
If I move the field decleration out of the partial class into another class not related to LINQ-SQL, then I get the following:
Object reference not set to an instance of an object
If I pass the fields through as an argument, then I see no errors and the query works fine and generates the expected SQL.
An example is as below:
partial class Order
{
public static readonly string Complete = "Complete";
public static readonly string Pending = "Pending";
public static readonly Func<DataContext, Order, bool> IsComplete =
CompiledQuery.Compile((DataContext context, Order o) =>
Complete == o.Status);
}
Usage:
var test = from o in db.Orders
select new
{
IsComplete = Order.IsComplete(db, o)
};
This generates the errors mentioned. If I add a string[]
as another argument to the CompiledQuery
then I see no errors. Also, If I modify the strings to be const
instead of static readonly
this works as well, but I imagine that is due to the values being assigned at compile time.
Is there any way of getting the static readonly
fields working?
Upvotes: 4
Views: 547
Reputation: 18474
The problem is occuring because Linq-To-Sql is trying to translate your expression into the backend SQL, because the logic sees an unmapped class member it cannot cope with converting it.
I would suggest you create a wrapping property to do the work for you
partial class Order {
public static readonly string Complete = "Complete";
public static readonly string Pending = "Pending";
private static readonly Func<DataContext, Order, bool> _isComplete;
public static Func<DataContext, Order, bool> IsComplete {
get {
if (_isComplete == null) {
var complete=Complete;
_isComplete CompiledQuery.Compile((DataContext context, Order o) =>
complete == o.Status);
}
return _isComplete;
}
}
}
}
Upvotes: 2
Reputation: 41243
There is no problem if you're not mixing normal queries and compiled queries. The following works and will give you better performance overall, at the cost of not being able to reuse a simple IsCompleted
compiled everywhere you like.
public static readonly Func<YourDataContext, IEnumerable<Order>> GetCompletedOrders =
CompiledQuery.Compile((YourDataContext context) =>
context.Orders.Where(o => Complete == o.Status));
Upvotes: 0