When I use the query
var NewMatchs = (from x in entity.matches select x).LastOrDefault();
I get error like this
LINQ to Entities does not recognize the method 'SocialSports.Models.match
LastOrDefaultmatch'
method, and this method cannot be
translated into a store expression.
What's wrong in my code ???
Thanks...
LastOrDefault is not supported in Linq to Entities. You can achieve the same using the following:
var lastmatch = (from x in entity.matches select x)
// Assuming you have some kind of timestamp
.OrderByDescending(s => s.Date)
.FirstOrDefault();
You can't use LastOrDefault to query EF entities, as it cannot be translated to T-SQL.
Not all the LINQ methods are supported by Linq to Entities.
List of ALL supported / not supported methods:
http://msdn.microsoft.com/en-us/library/bb738550.aspx
You could try
var NewMatchs = (from x in entity.matches select x).ToList().LastOrDefault();
but this will load ALL matches from the db and perform Linq to objects.
Or try sorting and call FirstOrDefault.
See The query operator 'LastOrDefault' is not supported
Related
I am using Linq to Entities and am getting this error
The method Distinct is not supported
On this line of code
var typeIds = _context.AttributeValues.Select(av => av.AttributeTypeId).Distinct();
Why is this?
As per MSDN few LINQ methods are not supported which using OData service. Below is a partial list of unsupported methods.
All
Any
Concat
DefaultIfEmpty
Distinct
Except
Intersect
Union
Zip
For a full list of unsupported operations see here
However, as a workaround following statement should work in this case.
var typeIds = _context.AttributeValues
.Select(av => av.AttributeTypeId)
.AsEnumerable()
.Distinct();
A solution is to define a WCF Data Service using (server-side) the QueryByCube method provided by my product AdaptiveLINQ (www.adaptivelinq.com). This method transforms a projection (expressed by the select operator) in an aggregation.
You have just to define a cube with one dimension : AttributeTypeId
av => av.AttributeTypeId
Define a Data Service providing the queryable collection:
yourDbContext.AttributeValues.QueryByCube(yourCube);
Now you can query your service using the OData protocol:
http://.../myService.svc/AttributeValues?$select=AttributeTypeId
Or, if your using a C# client:
serviceContext.AttributeValues.Select(x => x.AttributeTypeId);
The advantage of this solution relative to the workaround proposed A J Qarshi is that the distinction is made on the server side.
I have the following LINQ query in VB.NET
Using db As New ReablementLSQLDataContext
query = (From b In db.Visits
Join c In db.LinkStaffToVisits On b.ID Equals c.VisitID
Where c.StaffID = staffid And b.StartEpoch = newepochdatetime).ToList()
End Using
When I run this, it returns a list of type anonymous which means its pretty useless if I want to access any of the data in it. How do I run this join statement and return a list of a concrete type?
Anonymous types as query results aren't so "useless", since you can always foreach over them (locally). Still, if you want a concrete type, you can add a select statement at the end and project the anonymous result into your type (supposed that you made this type and know which fields to use where), like (C# syntax)
var newQuery = query.Select(anon_x => new YourType(anon_x.field1, anon_x.field2, ...))
You can use a generic version of ToList method. I am a C# developer and can provide syntax related to C# :
.ToList<YourType>();
For VB.Net version read : http://msdn.microsoft.com/en-us/library/bb342261.aspx#Y0
Works: My UI sends up entity sql sort expressions from a jqGrid to my DAL and then applies some Where clauses that get returned to my service layer. My service layer will then create a PaginatedList object that applies the Skip()..Take() to the IQueryable.
Example:
var qry = ((IObjectContextAdapter)DbContext).ObjectContext
.CreateQuery<TEntity>(entityName)
.OrderBy(pEntitySQLSort.GetEntitySQL());
//GetEntitySQL() i.e. "it.WorksheetID ASC"
return qry.Where(p=> pStatus == "blah").Skip(5).Take(10);
Doesn't Work: Applying a GroupBy() then Select() that returns a list of the same type of entities (Worksheet).
Example:
var qry = ((IObjectContextAdapter)DbContext).ObjectContext
.CreateQuery<TEntity>(entityName)
.OrderBy(pEntitySQLSort.GetEntitySQL());
var qryGrouped = qry.GroupBy(pWorksheet => pWorksheet.ParticipantID)
.Select(pGroup => new {Group = pGroup, LatestWorksheetID = pGroup.Max(pWorksheet => pWorksheet.WorksheetID)})
.Select(p => p.Group.FirstOrDefault(pWorksheet => pWorksheet.WorksheetID == p.LatestWorksheetID));
return qryGrouped.Skip(5).Take(10); //throws exception.
Throws NotSupportedException: The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
It seems to me that the first snippet does return an IOrderedQueryable that applies the esql sorting expression but the second snippet does not? Or maybe does GroupBy() remove the ordering of a query/collection ? If this is is the case, and since esql must be applied BEFORE LINQ to Entities, how could I accomplish the sql sorting + LINQ GroupBy ?
Related:
When is ObjectQuery really an IOrderedQueryable?
Why can't we mix ESQL and LINQ TO Entities
GroupBy() returns an IGrouping<int, Worksheet>. The actual object is an ObjectQuery returned as IQueryable. You linked to my question (When is ObjectQuery really an IOrderedQueryable?), so you know that the fact that this ObjectQuery also implements IOrderedQueryable does not necessarily mean that it actually behaves as such.
In a more elementary, related, question, Jon Skeet made the distinction between actual type and compile-time type. The compile-time type (IQueryable) is what matters.
So, GroupBy effectively cancels the previous OrderBy. In a quick test on a similar case I could see that even the ordering is gone in the grouping. Conclusion: you'll have to re-apply an OrderBy for the Skip to be executed successfully.
I have some thing like this
SecuritySearcher sc = new SecuritySearcher();
Dictionary<string, bool> groupsMap =
sc.GetUserGroupMappings(domainName, currentUser, distGroups.ToList());
IQueryable<HotelTravel> groupq =
(from hotel in qHs
join hp in qHps on hotel.HotelTravelId equals hp.HotelTravelId
where !string.IsNullOrEmpty(hp.GroupName)
&& groupsMap.ContainsKey(hp.GroupName)
&& groupsMap[hp.GroupName] == true
select hotel);
While executing Linq statement it is throwing exception saying
LINQ to Entities does not recognize the method 'Boolean ContainsKey(System.String)' method, and this method cannot be translated into a store expression.
In order to translate your expression into a database query, the database would somehow have to know the contents of your dictionary and have a way to access it from the query. There is no dictionary mechanism in SQL, but that doesn't matter because you don't need a dictionary because you're just looking for keys whose value is a certain constant. You can turn that set of keys into a list and see if that list contains what you're looking for:
var groupsList = (from kvp in groupsMap // find all keys in groupsMap
where kvp.Value == true // where the value is set to True
select kvp.Key).ToList();
IQueryable<HotelTravel> groupq =
from hotel in qHs
join hp in qHps on hotel.HotelTravelId equals hp.HotelTravelId
where !string.IsNullOrEmpty(hp.GroupName)
&& groupsList.Contains(hp.GroupName)
select hotel;
I suspect that you don't actually have the empty string as a key in your dictionary, though, which means you can get rid of the IsNullOrEmpty call and just have where groupsList.Contains(hp.GroupName).
I had the same issue. The easiest solution is to replace the method
where groupsMap.ContainsKey(hp.GroupName)
with the method with the same functionality that is recognized by LINQ to Entities:
where groupsMap.Keys.Contains(hp.GroupName)
As the answer here says, these two functions do exactly the same thing.
You are not allowed to use your dictionary in the WHERE clause to limit your result set because LINQ To Entities will try to turn this into SQL and unfortunately, it doesn't know how to handle the Dictionary collection.
See this link: linq to entity framework: use dictionary in query
1) Binding to The following populates a READ ONLY WinFrms grid:
Dim query = (From profile _
In db.profile _
Where profile.employee.employeeId = employeeID _
Select profile.description)
Me.DataGridView.DataSource = profileQueryList
2) Binding to the entity itself makes the WinForms grid EDITABLE, but unfiltered:
Me.DataGridView.DataSource = db.profile
I need something that combines the filtering feature of #1 with the editable feature of #2.
Try to use an explicit ToList() call.
Me.DataGridView.DataSource = query.ToList()
I guess that else only the expression tree of the query is bound and the entities are only fetched on demand.
Found the solution! It's documented in:
Linq to Entities Filtering an Entity Dynamic/Strongly Typed
Don't bind directly to the queryable. Instead, you need to go through the EntityDataSource class. Note, especially, this article on how to filter data with this control.