Linq to Entities Does Not Recognize the Method Last. Really

LINQ To Entities does not recognize the method Last. Really?

That limitation comes down to the fact that eventually it has to translate that query to SQL and SQL has a SELECT TOP (in T-SQL) but not a SELECT BOTTOM (no such thing).

There is an easy way around it though, just order descending and then do a First(), which is what you did.

EDIT:
Other providers will possibly have different implementations of SELECT TOP 1, on Oracle it would probably be something more like WHERE ROWNUM = 1

EDIT:

Another less efficient alternative - I DO NOT recommend this! - is to call .ToList() on your data before .Last(), which will immediately execute the LINQ To Entities Expression that has been built up to that point, and then your .Last() will work, because at that point the .Last() is effectively executed in the context of a LINQ to Objects Expression instead. (And as you pointed out, it could bring back thousands of records and waste loads of CPU materialising objects that will never get used)

Again, I would not recommend doing this second, but it does help illustrate the difference between where and when the LINQ expression is executed.

LINQ to Entities does not recognize the method: LastOrDefault

LastOrDefault() isn't supported by Linq To Entities. So it will work on a collection in memory, but not when you're attempting to query a database .

This is an efficient way to handle it:

var lastCompletedQuestion = 
_db.CompletedQuestions.Where(q => q.UserId == currentUserId)
.OrderByDescending(q => q.QuestionNumber)
.FirstOrDefault()

;

LINQ to Entities does not recognize the method

As you've figured out, Entity Framework can't actually run your C# code as part of its query. It has to be able to convert the query to an actual SQL statement. In order for that to work, you will have to restructure your query expression into an expression that Entity Framework can handle.

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
string name = this.charityName;
string referenceNumber = this.referenceNumber;
return p =>
(string.IsNullOrEmpty(name) ||
p.registeredName.ToLower().Contains(name.ToLower()) ||
p.alias.ToLower().Contains(name.ToLower()) ||
p.charityId.ToLower().Contains(name.ToLower())) &&
(string.IsNullOrEmpty(referenceNumber) ||
p.charityReference.ToLower().Contains(referenceNumber.ToLower()));
}

LINQ to Entities does not recognize the method in c#

According to Supported and Unsupported LINQ Methods (LINQ to Entities), Last and LastOrDefault methods are unsupported.

If you expect zero or one records, simple replace the LastOrDefault with FirstOrDefault.

Otherwise use something like this:

var shopCom = _entities.ShoppingComments
.Where(XX => XX.UserId == obj.UserId &&
XX.ShoppingScoreTypeId ==obj.TypeId &&
XX.WhichId == obj.Id &&
XX.CommentDate ==objShoppingComment.CommentDate &&
XX.Commnet ==objShoppingComment.Commnet)
.OrderByDescending(XX => XX.SomeField)
.FirstOrDefault();

LINQ to Entities does not recognize the method

you have a parenthesis in the wrong spot in your LINQ:

db.Products.OrderBy(x => x.Name.Skip(pageno* 8).Take(8).ToList());

You want:

db.Products.OrderBy(x => x.Name).Skip(pageno* 8).Take(8).ToList();

As it is, it's not actually performing the query until the view (and then erroring), because you aren't calling ToList on the outer query. EF only retrieves the data when it is needed.

The latter query is very common for pagination. The former doesn't really make sense.

LINQ to Entities does not recognize the method

You can use conditionals inside LINQ to Entity queries:

AverageRating = u.ReviewsReceived.Count(r => r.IsActive && r.IsVisible) > 0 ? 
u.ReviewsReceived.Where(r => r.IsActive && r.IsVisible).Sum(r => r.Rating) /
u.ReviewsReceived.Count(r => r.IsActive && r.IsVisible)
: 0

This will be calculated by the server, and returned as part of your list. Although with 10 million rows like you said, I would do some serious filtering before executing this.

LINQ to Entities does not recognize the method in query

    var orderList = _context.Set<FixedOrder>()
.Include(fo => fo.Client)
.ForCurrentDay(date)
.Where(fo => !fo.Client.IsInactive)
.ConsideringOrderSubstitution(orderSubstitutes.Select(os => os.FixedOrderId).ToList())
.Join(clientSet
, o => o.ClientId
, c => c.Id
, (o, c) =>
new
{
OrderId = orderSubstitutes.Where(os => os.FixedOrderId == o.Id).Select(os => os.OrderId).FirstOrDefault() ?? 0,
Client = c,
HasFixedOrders = true,
FixedOrderId = o.Id,
HasSpecialProducts = false
}
).ToList()
.Select(t=>new OrderDTO {
OrderId = t.OrderId,
ClientId = t.Client.Id,
ClientName = t.Client.Name,
HasFixedOrders = t.HasFixedOrders,
FixedOrderId = t.FixedOrderId,
ShippingHour = GetShippingHour(t.Client,date),
HasSpecialProducts = t.HasSpecialProducts
}).ToList();


Related Topics



Leave a reply



Submit