LINQ to Entities does not recognize the method exception - asp.net-mvc

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

Related

Odata Url conversion with descending orderby

i need to get data by descending orderby Visidate of patient so i tried url like this
192.168.1.105:33396/FalconCPDataService.svc/DEPhysicians?$format=json&$expand=DEPatientVisits&$orderby=DEPatientVisits/VisitDate+desc
but showing exception
{"odata.error":{"code":"","message":{"lang":"en-US","value":"The parent value for a property access of a property 'VisitDate' is not a single value. Property access can only be applied to a single value."}}}
The reason is that DEPatientVisits is not a single valued navigation property, so it is unable to append a property name to it. If it is a single valued, it works fine, such as:
http://services.odata.org/v4/OData/OData.svc/Products?$expand=Supplier&$orderby=Supplier/Name
Thanks for inviting.
I am not fully understand your question. you want to sort entities in DEPhysicians? or DEPatientVisits?
If you are try to get DEPhysicians inline expand DEPatientVisits, and want sort entities in DEPatientVisits by VisitDate, you can try:
locolhost/FalconCPDataService.svc/DEPhysicians?$format=json&$expand=DEPatientVisits($orderby=VisitDate desc)
If you are try to sort entities in DEPhysicians according to DEPatientVisits\VisitDate, then, just as the answer from #tanjinfu, DEPatientVisits should not be a collection. Otherwise, which VisitDate of entry in DEPatientVisits you want to used to sort?

Exception in System.Data.Entity.dll but was not handled in user code

I need to count the number of the rows in my database with the entity framework. I am using the LINQ method "Count".
Here is the code:
QvDb dba = new QvDb();
if (dba.KUser.Count(us => us.FacebookId == values["FacebookId"]) == 0)
As you can see the values["FacebookId"] it's a post array variable, and the dba object variable it's the database model builder.
When I am trying to access to the page i got this exception:
An exception of type 'System.NotSupportedException' occurred in
System.Data.Entity.dll but was not handled in user code
Additional information: LINQ to Entities does not recognize the method
'System.String get_Item(System.String)' method, and this method cannot
be translated into a store expression.
For the record, the array is not null. It is a string that posted from the form.
When using LINQ to entities, all parts of your LINQ statement must be supported by the database.
values["FacebookId"] is a local dictionary. So it cannot be executed on the remote SQL database.
Pull the value from the dictionary first into a local variable, then execute your LINQ statement.
QvDb dba = new QvDb();
var id = values["FacebookId"];
if (dba.KUser.Count(us => us.FacebookId == id) == 0)

LINQ join in VB.NET return concrete type rather than anonymous

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

Entity SQL Sort Then LINQ to Entities GroupBy Doesn't Return IOrderedQueryable

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.

Lazy fetching of objects using FindAllBy , for the first time

When I use criteria queries, the result contains array list of lazy initialized objects. that is, the list has values with handler org.codehaus.groovy.grails.orm.hibernate.proxy.GroovyAwareJavassistLazyInitializer.
This prevent me from doing any array operation (minus, remove etc) in it. When I use, GORM methods, I get array list of actual object types. How can I get the actual objects in criteria query?
The code is listed below.
availableTypes = Type.withCriteria() {
'in'("roleFrom", from)
'in'("roleTo", to)
}
availableTypes (an array list) has one value , but not actual object but value with a handler of GroovyAwareJavassistLazyInitializer
availableTypes (an array list) has values with type Type
availableTypes = Type.findByRoleFrom(from)
---------- Update ----------
I did further troubleshooting, and this is what I found. Probably the above description might be misleading, but I kept it in case it helps.
When using findAllBy for the first time, I get proxy objects rather than the actual instance. Then, I invoke the method through an ajax call, the actual instance is loaded (anything to do with cache loading??). When I refresh the page, it again loads the proxy
def typeFrom = Type.findAllByParty(partyFrom)
there is another use of findAllBy in the same method, which always returns actual instances.
def relFrom = Relation.findAllByParty(partyFrom)
When compared the two classes, the attribute 'party' of class Roles is part of a 1-m relation. like
class Role {
RoleType roleType
LocalDate validFrom
LocalDate validTo
static belongsTo = [party : Party ]
...
}
I know if I do statement like Party.findAll(), the role instances would be proxy till they access. But, when using gorm directly on the class (Role), why I am getting the proxy objects ???
thanks for the help.
thanks.
Turns out are a couple of possible solutions which I came across but didn't try, such as
Overloading the equals method so that the proxy and the domain
object use a primary key instead of the hashCode for equality
Using a join query so that you get actual instances back and not proxies
GrailsHibernateUtil.unwrapProxy(o)
HibernateProxyHelper.getClassWithoutInitializingProxy(object)
One solution that worked for me was to specify lazy loading to be false in the domain object mapping.
History of this problem seems to be discussed here: GRAILS-4614
See also: eager load

Resources