I have a query that is read only and returns a large number of entities.
I do not want change tracking or knockout wrapping for this query.
Is there a way to disable?
If you return results as a projection then Breeze will not try to wrap them. So
var q = EntityQuery.from("Customers");
will return "wrapped" Customer objects. However if you write
var q = EntityQuery.from("Customers").select( "companyName, address, city")
then Breeze will return an array of anon "unwrapped" objects each with 3 properties ( "companyName", "address" and "city").
I can't really think of another approach, if you really want entire entities but do not want to Breeze to "wrap" them. But... this does seem like a reasonable request, so please add a User Voice feature request for an ability to mark a query as "noTracking". We take these requests seriously.
Related
I have a breeze query to fetch some values from my database.
If I want to order the values alphabetically, then the query looks like this:
var query = EntityQuery.from("Words")
.orderBy("Text");
The thing is I want to sort the values returned first by length, then alphabetically.
For example, this set of results is ordered alphabetically:
a
ab
b
bb
How do I make it ordered like this:
a
b
ab
bb
??
I know I can write a function to order the data the way I want to AFTER it's returned from the server, but I'm wondering if it's possible to change the query so the data will be sorted like described above just by changing the query?
You can accomplish this by adding an additional filter step on the server before sending the data back to the client.
[HttpGet]
public IQueryable<Word> Words() {
return ContextProvider.Context.Words.ToList().OrderBy(customOrderByImpl;
}
This may be less than performant because with your example I don't think that you can take advantage of any database sorting ( at least thru EF). This is why the call to ToList occurs before sorting the results in memory on the server.
Hope this makes sense.
Is it possible to change the way indexes are used in TClientDataSet to sort records? After reading this question, I thought it would be nice to be able to sort string fields logically in a client dataset. But I have no idea how to override default behavior of client dataset when it comes to indexes. Any ideas?
PS: My CDS is not linked to any provider. I'm looking for a way to modify the sort mechanism of the TClientDataSet (or the parent in which the mechanism is implemented) itself.
You cannot override the sort mechanism of a ClientDataSet - unless you rewrite the according part of Midas.
To achieve the correct sorting (whatever logical means) you can introduce a new field and set its values in a way so that, sorted with the standard mechanism, they will give the required sort order.
Read the excellent on-line article Understanding ClientDataSet Indexes by Cary Jensen.
It explains how to use various ways of sorting and indexing using IndexDefs, IndexFieldNames and IndexName.
Edit: reply to your comment.
You cannot override a sorting method in TClientDataSet, but you can add do this:
If you want to do custom sorting on anything else than existing fields, then you have to add a Calculated Field, perform a kind of order calculation in the OnCalcFields event, then add that field to the IndexDefs.
I would try to achieve the desired sort with an SQL statement that feed the ClientDataSet.
For example if I was dealing with the following strings in FieldN
a_1
a_20
a_10
a_2
and I wanted them sorted like this (I assume this is similar to what you mean by logically
a_1
a_2
a_10
a_20
then I would write the SQL as
SELECT FieldA,
FieldB,
... ,
FieldN,
CAST(SUBSTRING(FieldN, 3, 2) TO INTEGER) As FieldM '<== pseudocode
FROM TableA
ORDER BY FieldM
The exact syntax of the SubString and Cast to Integer operations will depend on which DBMS you're using.
I've created a WebApi project in VS 2012, using NHibernate as my ORM and I intend to enable Odata support on it. So I've created a test controller with a single Get method that returns a list of entities from a table on my database.
Everything works fine, I can use OData to filter and order my results, etc. The problem is I couldn't find a way to limit the amount of data that's being returned from the database to the controller, and this table has millions of records in it.
Using the PageSize property of the Queryable attribute only seems to be limiting the amount of data returned to the client, but no the amount of Data returned from the DB.
I've tried applying a Take(n) on the IQueryable inside the get method before returning it, and it limits the results brought back from the DB, but it breaks the OData filtering, since if you try to query an entity that's not in the first n results, it just returns an empty collection.
I know you can use the $Top parameter on OData to accomplish this, but I would like not to depend on the client/consumer providing it in order to ensure that I'm not unnecessarily bringing thousands or even million of records that I'm not going to use.
I've also tried to manually check if the client provided a Top parameter on the query string, apply the OData transformation to my Queryable and then applying the Take(n) method over the transformed query. This approach enabled me to filter for any entity through OData, but it breaks pagination, because if I use the $Skip=n parameter, it again returns an empty collection.
So, is there any way to reliably limit the results fetched from the DB while not breaking the OData support?
We recently found that too. We are not applying a Take(pageSize) when server driven paging is enabled as we have to figure out if a next page link should be generated or not. We just enumerate the result set for pageSize number of entities and check if there are more entities or not. We thought that most providers generally bring a partial set of results as IQueryable is generally a lazy implementation. Turns out that is not true. Also, the database can optimize the query if it knows only pageSize number of results are required.
This is the issue that was opened for it. Good news is Youssef fixed it already :). This is the commit that fixed it. So, if you grab the nightly builds you should be good.
My objective:
I have built a working controller action in MVC which takes user input for various filter criteria and, using PredicateBuilder (part of LinqKit - sorry, I'm not allowed enough links yet) builds the appropriate LINQ query to return rows from a "master" table in SQL with a couple hundred thousand records. My implementation of the predicates is totally inelegant, as I'm new to a lot of this, and under a very tight deadline, but it did make life easier. The page operates perfectly as-is.
To this, I need to add a Full-Text search filter. Understanding the way LINQ translates Contains to LIKE(%%), using the advice in Simon Blog: LINQ-to-SQL - Enabling Full-Text Searching, I've already prepared Table Functions in SQL to run Freetext queries on the relevant columns. I have 4 functions, to match the query against 4 separate tables.
My approach:
At the moment, I'm building the predicates (I'll spare you) for the initial IQueryable data object, running a LINQ command to return them, like so:
var MyData = DB.Master_Items.Where(outer);
Then, I'm attempting to further filter MyData on the Keys returned by my full-text search functions:
var FTS_Matches_Subtable_1 = (from tbl in DB.Subtable_1
join fts in DB.udf_Subtable_1_FTSearch(KeywordTerms)
on tbl.ID equals fts.ID
select tbl.ForeignKey);
... I have 4 of those sets of matches which I've tried to use to filter my original dataset in several ways with no success. For instance:
MyNewData = MyData.Where(d => FTS_Matches_Subtable_1.Contains(d.Key) ||
FTS_Matches_Subtable_2.Contains(d.Key) ||
FTS_Matches_Subtable_3.Contains(d.Key) ||
FTS_Matches_Subtable_4.Contains(d.Key));
I just get the error: The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Too many parameters were provided in this RPC request. The maximum is 2100.
I get that it's because I'm trying to pass a relatively large set of data into the Contains function and LINQ is converting each record into a separate parameter, exceeding the limit.
I just don't know how to get around it.
I found another post linq expression to return property value which seemed SO promising. I tried ifwdev's solution (2nd highest ranked answer): using LinqKit to build an extension that will break up the queries into manageable chunks. But I can't figure out how to implement it. Out of my depth right now maybe?
Is there another approach that I'm missing? Some simpler way to accomplish this that I've overlooked?
Sorry for the long post. But thank you for any help you can provide!
This is a perfect time to go back to raw ado.net.
Twisting things around just to use linq to sql is probably just as time consuming if you wrote the query and hydration by hand.
This is probably a very simple question that I am working through in an MVC project. Here's an example of what I am talking about.
I have an rdml file linked to a database with a table called Users that has 500,000 rows. But I only want to find the Users who were entered on 5/7/2010. So let's say I do this in my UserRepository:
from u in db.GetUsers() where u.CreatedDate = "5/7/2010" select u
(doing this from memory so don't kill me if my syntax is a little off, it's the concept I am looking for)
Does this statement first return all 500,000 rows and then filter it or does it only bring back the filtered list?
It filters in the database since your building your expression atop of an ITable returning a IQueryable<T> data source.
Linq to SQL translates your query into SQL before sending it to the database, so only the filtered list is returned.
When the query is executed it will create SQL to return the filtered set only.
One thing to be aware of is that if you do nothing with the results of that query nothing will be queried at all.
The query will be deferred until you enumerate the result set.
These folks are right and one recommendation I would have is to monitor the queries that LinqToSql is creating. LinqToSql is a great tool but it's not perfect. I've noticed a number of little inefficiencies by monitoring the queries that it creates and tweaking it a bit where needed.
The DataContext has a "Log" property that you can work with to view the queries created. I created a simple HttpModule that outputs the DataContext's Log (formatted for sweetness) to my output window. That way I can see the SQL it used and adjust if need be. It's been worth its weight in gold.
Side note - I don't mean to be negative about the SQL that LinqToSql creates as it's very good and efficient almost every time. Another good side effect of monitoring the queries is you can show your friends that are die-hard ADO.NET - Stored Proc people how efficient LinqToSql really is.