I am doing a query with linq and entity framework. The database I'm using is Oracle. Here is the code :
Entities bdd = contextWrapper.GetContext();
data = (from table in bdd.COP_PRDTICSOURES
where (table.IDTTIC==ticketId && table.IDTPRD==productId)
select table).AsEnumerable();
When I look at the variable bdd.COP_PRDTIC_SOURES using a debugger, it contains an entry matching my two criteria. However, after the execution of the query, the data variable contains no result.
Is there something wrong with my syntax ?
Some additional information:
The entity i'm looking for isn't commited in the database when I perform this query. It's created before in the same transaction.
I use a foreach on the data after, so it's not a problem of lazy loading.
AsEnumerable does not load data from DB. Calling it you are not executing the actual query, just changing how it is going to be executed in its entirety.
Use ToArray or ToList instead to load data explicitly. Or call foreach on this collection.
Related
I having some trouble with a Linq NHibernate query.
I need to get a batch of vouchers with their details. As I need to iterate them, I wanted to get all the information in a single execution.
My query is the following one:
return this.Session.Query<VouchersToIntegrate>()
.Take(query.BatchSize)
.Fetch(x => x.VoucherLines)
.ToList();
Where VouchersToIntegrate is the voucher and VoucherLines the lines of each voucher.
The batchSize is set to 50.000 now, but when I return all the objects, I just get 23XXX. This is because I guess the framework is internally executing a distinct after it gets all the objects from the database (client-side). Is there any other way to get the 50.000 objects with the distinct filter in the SQL server side?
Thanks
There is not a way to construct this query with NHibernate's LINQ provider.
You can, however, construct the appropriate SQL query by hand and then map it to entities using NHibernate's "Native SQL" API: http://nhibernate.info/doc/nhibernate-reference/querysql.html.
I have this C# L2S code:
Table<ERPRaw> linqRawFile = db.GetTable<RawFile>();
var linqNameList =
from row in linqRawFile.AsEnumerable()
select row.fileName;
currentFileNameList = linqNameList.ToArray();
It's supposed to read only the fileName field, but when I check in the SQL server profiler, I see that this query triggers full record loading. The fields contain file binary data, so the full table loading takes considerable time. Retrieving just the fileName field takes only few milliseconds.
What would be the right way to retrieve only fileName field of RawFile in as an array of strings? I assume that the linq framework now loads each RawFile record in full, as it doesn't see I will retrieve only the fileName property from the list.
Perhaps I have to construct the query without referencing the linqRawFile at all? Wouldn't that be kind of ignoring the reason linq is introduced in the project, to abstract the database layer away?
It's supposed to read only the fileName field
No, it does not. Here is what is going on: your query execution happens in two places - in RDBMS and in memory. The db.GetTable<RawFile>() happens in RDBMS; everything after it happens in memory, because you use AsEnumerable().
The portion of the query where the projection happens (i.e. row.fileName column is extracted from the whole row) is happening in memory. The RDBMS part of the query does not know about this projection. db.GetTable<RawFile>() is all the SQL-generating LINQ provider sees, so naturally it returns the entire row.
If you write a combined query against your SQL source, the projection will happen in SQL:
var linqNameList =
from row in db.GetTable<RawFile>()
select row.fileName;
You should be able to replace the whole thing with this:
var currentFileNameList = db.GetTable<RawFile>().Select(r => r.fileName).ToArray();
I'm using C#, .NET (4.0) and Entity Framework to connect to SQL CE 4.0.
I query some objects with specific properties, but the query returns only objects that meet search criteria only if that data was already saved to database, which is not that problematic, bigger problem is that if data is changed, but not yet saved to database it will still meet search criteria.
Example:
var query = from location in mainDBContext.Locations
where location.InUse == true
select location;
This query returns also objects where location.InUse = false if InUse was true when loaded from DB and then changed later on in code.
This is screen capture from one of the query results objects.
I really don't understand why it does this. I would understand if this query would always query database and I would get the older version of this object (thus InUse would be true).
Thank you for your time and answers.
That is how EF works internally.
Every entity uniquely identified by its key can be tracked by the context only once - that is called identity map. So it doesn't matter how many times did you execute the query. If the query is returning tracked entities and if it is repeatedly executed on the same context instance it will always return the same instance.
If the instance was modified in the application but not saved to the database your query will be executed on the database where persisted state will be evaluated but materialization process will by default use the current data from the application instead of data retrieved from the database. You can force the query to return state from the database (by setting mainDBContext.Locations.MergeOption = MergeOption.OverwriteChagens) but because of identity map your current modifications will be lost.
I'm not really sure what exactly your problem is, but I think you have to know this:
That kind of query always return data that is submitted into DB. When you change some entities in your code but they are not submitted into database the LINQ query will query the data from database, without your in-code changes.
LINQ queries use Deferred Execution, so your 'query' variable is not a list of results, it's just a query definition that is evaluated each time results are needed. You should add .ToList() to evaluate that query and get a list of results in that certain line of code.
An example for .ToList():
var query = (from location in mainDBContext.Locations
where location.InUse == true
select location).ToList();
I just ran into the same thing myself. It's a bit messy, but another option is to examine the Local cache. You can do this, for example:
var query = from location in mainDBContext.Locations.Local
where location.InUse == true
select location;
This will only use the local cache not saved to the database. A combination of local and database queries should enable you to get what you want.
I have a query that returns a resultset. And I want to apply filter and sorting on the resultset.
Can someone help me understand if I use the query in LINQ (I'm using EF 4.0), will I be able to get deferred executuin so that when i apply filter/sort in entity model, the execution happens only one time (deffered)
Thanks in advance!
Regards,
Bhavik
If the query takes no parameters, then yes, as you could make a view that calls that sproc, expose the view in your model, then query it.
If it takes parameters, then if you need the sort/filter done server-side, then I think you'd have to add a wrapper sproc (or modify the existing one) to pass in the sort and filter to perform (basically, do it manually, but at least server-side).
Alternatively, you could write the sql to do it server side (sproc results into temp table, then select from that temp table and apply filtering, still manually) and then ExecuteStoreQuery
No, you can't defer the execution of a linq filtering to the stored proc in sql. The stored proc will be executed first, a resultset will be returned, you can then cast it to a list of your object types, once done that you can filter using Linq.
You can easily cast the resultset to a list of your objects using context.Translate<>
Have a look to these links :
enter link description here
List item
Of course the query (in your code) will not be evaluated until you cast it to a list, so you can concatenate all the filtering you want to your resultset and then call the ToList() to get the results.
Using the Entity Framework, when one executes a query on lets say 2000 records requiring a groupby and some other calculations, does the query get executed on the server and only the results sent over to the client or is it all sent over to the client and then executed?
This using SQL Server.
I'm looking into this, as I'm going to be starting a project where there will be loads of queries required on a huge database and want to know if this will produce a significant load on the network, if using the Entity Framework.
I would think all database querying is done on the server side (where the database is!) and the results are passed over. However, in Linq you have what's known as Delayed Execution (lazily loaded) so your information isn't actually retrieved until you try to access it e.g. calling ToList() or accessing a property (related table).
You have the option to use the LoadWith to do eager loading if you require it.
So in terms of performance if you only really want to make 1 trip to the Database for your query (which has related tables) I would advise using the LoadWith options. However, it does really depend on the particular situation.
It's always executed on SQL Server. This also means sometimes you have to change this:
from q in ctx.Bar
where q.Id == new Guid(someString)
select q
to
Guid g = new Guid(someString);
from q in ctx.Bar
where q.Id == g
select q
This is because the constructor call cannot be translated to SQL.
Sql's groupby and linq's groupby return differently shaped results.
Sql's groupby returns keys and aggregates (no group members)
Linq's groupby returns keys and group members.
If you use those group members, they must be (re-)fetched by the grouping key. This can result in +1 database roundtrip per group.
well, i had the same question some time ago.
basically: your linq-statement is converted to a sql-statement. however: some groups will get translated, others not - depending on how you write your statement.
so yes - both is possible
example:
var a = (from entity in myTable where entity.Property == 1 select entity).ToList();
versus
var a = (from entity in myTable.ToList() where entity.Property == 1 select entity).ToList();