I'm trying to get the query string with parameters for debugging purposes from entity framework. No, I will not use EFProfiler because the query strings need to be visible as an output on the page. Most of those queries are written manually, using ExecuteStoredQuery(). However, casting them to ObjectQuery yields null.
Example:
ObjectResult<Parent> model = _context.ObjectContext().ExecuteStoreQuery<Parent>("SELECT * FROM Parents");
var objectQuery = model.AsQueryable() as ObjectQuery<Parent>;
objectQuery is null. ObjectContext() is a simple method in the datacontext that looks like:
return (this as IObjectContextAdapter).ObjectContext;
I have exhausted my own ideas and anything that is yielded back from searches is... well, useless, because nobody seems to get that problem. Mind, the results come back correctly from the query.
Edit: Right, I should have mentioned this, as well.
Doing this:
var oq = m as ObjectQuery<Parent>;
Yields me this:
Cannot convert type 'System.Data.Objects.ObjectResult' to 'System.Data.Objects.ObjectQuery' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
Whence is when I thought it needed to be cast AsQueryable(), which, well... is null, for obvious reasons. It was my tired head that forgot to add this little detail.
I think the other anwers made clear that you can't cast an ObjectResult<T> to an ObjectQuery<T>. But I'm interested in your comment
I tried CreateQuery and I ran into problems with it. For one, it doesn't like when the user tries to SELECT *, you seem to have to specify all the fields you need to get.
You can use an ObjectQuery to do a "*" search:
ObjectContext().ObjectQuery<Parent>("SELECT VALUE par FROM Parents AS par")
As you see, there is no actual * in the query string and the trace string doesn't have a * but shows all fields. But you don't have to specify all field to build the query string. I hope this will help you to make better use of ObjectQuery.
Your cast as ObjectQuery<Parent> is not correct, cause ObjectResult<Parent>.AsQueryable() will return an IQueryable<Parent> that is not of type ObjectQuery<Parent>.
AsQueryable is the extension method of the class Queryable that converts an IEnumerable to an IQueryable.
The result is that your variable objectQuery is null.
Surely you ACTUALLY want to use CreateQuery(sql) rather than ExecuteStoreQuery(sql).
Given the name, ExecuteStoreQuery actually runs the SQL, whilst CreateQuery returns an ObjectQuery ready to be sent to the database.
Obviously you can then call Execute on ObjectQuery to return the ObjectResult
Related
I am trying to achieve a simple task, and I don't find a way to do it. I am trying to convert a LINQ result to a list of objects. I am following the syntax posted in this accepted SO answer.. Here is my code:
var LinqHallazgos = (from RA_Hallazgos in context.RA_Hallazgos
select new
{
HallazgoId = RA_Hallazgos.HallazgoId,
Hallazgo = RA_Hallazgos.Hallazgo
});
List<RA_Hallazgos> Hallazgos = LinqHallazgos.ToList<RA_Hallazgos>();
And this is the error that I get:
It says that "LinqHallazgos", which is an iqueryable, doesn't contain a definition for ToList. But I see the "ToList" method in intellisense. It also says that it expect an IEnumerable but this answer seems to use similar syntax.
What I am doing wrong and how in the world I get the LINQ result as a list of a particular object??
You are making this too complex. It seems all you want to do is materialize the DbSet<RA_Hallazgos> to memory (retrieve the content from the database). If that is the case just use the ToList() linq extension on the DbSet and you are done. Note that it will retrieve everything as you did not specify a filter (ie. any limiting predicates like Where / Take / Skip / etc).
List<RA_Hallazgos> Hallazgos = context.RA_Hallazgos.ToList();
Just call .ToList(). You have an anonymous type there (the new {}) so you can't specify the type explicitly even if you wanted to.
Otherwise, if RA_Hallazgos is an actual type, use new RA_Hallazgos{} to avoid creating an anonymous type.
Try
select new RA_Hallazgos
{
HallazgoId = RA_Hallazgos.HallazgoId,
Hallazgo = RA_Hallazgos.Hallazgo
}
List<RA_Hallazgos> Hallazgos = LinqHallazgos.ToList()();
We are investigating using LinQ to query an internal dynamic collection created by Dapper. The question is:
How to execute dynamic LinQ against the collection using Scott Guthrie dynamic linq (or some other technology if possible)? (http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library)
This is what we want to do (much simplified):
Use Dapper to return a dynamic collection (here called rows):
rows = conn.Query(“select ACCOUNT, UNIT, AMOUNT from myTable”);
If we use a “static” LinQ query there is no problem. So this works fine:
var result = rows.Where(w => w.AMOUNT > 0);
But we would like to write something similar to this using dynamic Linq:
var result = rows.Where("AMOUNT > 0");
But we can’t get this to work.
The error we get is:
No property or field ‘AMOUNT’ exists in type ‘Object’
(We have tried a lot of other syntax also – but cant get it to work)
Please note: We do not want to use dynamic SQL when Dapper requests data from the database (that is easy). We want to execute many small dynamic Linq statements on the collection that the Dapper query returns.
Can it be that ScottGu dynamic Linq only works with ‘LinQ to SQL’?
Is there some other alternative approach to achieve the same thing?
(Performance is a key issue)
/Erik
conn.Query("...")
returns an IEnumerable<dynamic>. However, "dynamic LINQ" pre-dates dynamic, and presumably nobody has updated it to work with dynamic; it could certainly be done, but it is work (and isn't trivial). Options:
use Query<T> for some T
make the required changes to "dynamic LINQ", and preferably make those changes available to the wider community
I suspect that conn.Query(“select ACCOUNT, UNIT, AMOUNT from myTable”); returns IEnumerable<object>. In order for DLinq to work, you need to have IEnumerable<TheActualType>.
You can try this:
conn.Query<dynamic>("yourQueryString")
.ToList()
//.ToAnonymousList()
.Where("AMOUNT > 0");
If that doesn't work, you could try and use ToAnonymousList, that tries to return the IList<TheActualType.
I'm using Dynamic LINQ with NHibernate.
Simple example demonstrates my problem:
var q = sess.Query<User>().Select("new (Id, Login, Person.Id as PersonId)");
throws NullReferenceException when where are Users in database with User.Person == null.
This solves the problem:
var q = sess.Query<User>().Select(new { Id, Login, PersonId = (long?)Person.Id });
but I need something like
var q = sess.Query<User>().Select("new (Id, Login, (long?)Person.Id as PersonId)");
because select expression is generated dynamically.
Unfortunately dynamic LINQ does not understand cast to (long?) :(
What should I have to do?
Thanks in advance!
==== Edit ====
Ok, I understood two things:
1. Dynamic LINQ does not know about long, only Int64.
2. Cast is not '(Int64)something' but 'Int64(something)'.
So whole my code should be
sess.Query<User>().Select("new (Id, Login, Int64?(Person.Id) as PersonId)");
But it still does not solve my whole problem because NHibernate now fails with Could not execute query[SQL: SQL not available] exception and NullReference inner exception.
Finally I have mastered the problem. I studied Dynamic.cs and found that the Dynamic LINQ's syntax is very specific. Particularly the string expression "SomeType(SomeExpression)" generates cast expression only if SomeType has no constructor with one parameter. In other case it generates "new SomeType(SomeExpression)". I considered it as a mistake and slightly modified the Dynamic.cs.
Now in my example the cast can be made as 'Int64? Person.Id'. It is not a "normal" cast syntax but it works for me like a charm. Dynamic ExpressionParser is pretty good but unfortunately is not well adapted for C# cast syntax.
Also I registered in Dynamic.cs short type names like "long", "int" etc.
The modified source is downloadable here: http://1drv.ms/1cRJtSP .
I have the following lines of code in C#
that gets data using DataTables
This is pretty generic and helps me with multiple tables.
object obj = ((DataRowView)editingElement.DataContext).Row[this.SelectedValuePath];
I want to change this statement to a generic LINQ statement so that i can use it with multiple LINQ tables too.
Can somebody help me figure this out?
I don't think you can use LINQ to make the code you wrote nicer or more elegant in any way. I assume that the type of editingElement.DataContext is object, so you'll need to write the cast anyway. If you forget about the casting, your code is just indexed access:
var rows = (DataRowView)editingElement.DataContext;
object obj = rows.Row[this.SelectedValuePath];
LINQ doesn't have any features that would make indexing nicer, so I think this is the best you can get. One possible ugly thing is that you get object as the result and you'll need to cast that to some other type (e.g. CustomerInfo).
If you were using LINQ from the beginning (to populate the data for the DataContext), you could probably write something like this to access the customer:
var rows = (IEnumerable<CustomerInfo>)editingElement.DataContext;
CustomerInfo info = rows.Row[this.SelectedValuePath];
This would be a bit more elegant, because you'd need just a single cast. However, I think that your code is fine and LINQ cannot help you (in this piece of code).
Why does this throw System.NotSupportedException?
string foo(string f) { return f; }
string bar = "";
var item = (from f in myEntities.Beer
where f.BeerName == foo(bar)
select f).FirstOrDefault();
Edit: Here's an MSDN reference that (kind of) explains things...
Any method calls in a LINQ to Entities
query that are not explicitly mapped
to a canonical function will result in
a runtime NotSupportedException
exception being thrown. For a list of
CLR methods that are mapped to
canonical functions, see CLR Method to
Canonical Function Mapping.
See also http://mosesofegypt.net/post/LINQ-to-Entities-what-is-not-supported.aspx
EDIT: Okay, the code blows up because it doesn't know what to do with the call to foo(). The query is built up as an expression tree which is then converted to SQL.
The expression tree translator knows about various things - such as string equality, and various other methods (e.g. string.StartsWith) but it doesn't know what your foo method does - foo() is a black box as far as it's concerned. It therefore can't translate it into SQL.
The second version will fail as soon as you try to iterate over it. You can't use a locally defined method in an IQueryable<> where clause (of course, you can, but it will fail when the LINQ provider tries to translate it into SQL).
Because in the 2nd query no actual query is executed. Try adding ToList() where SingleOrDefault() is.
It's probably because the SQL-generation functionality isn't able to determine what to do with your foo() function, so can't generate output for it.