RavenDb 2.5 - TransformWith() not working after Where() - indexing

I am trying to perform a query where I need to filter on a property before I perform a transform, but the return type of Where() is IQueryable which apparently does not have a TransformWith extension method. What gives? The documentation examples show exactly this being performed.
session.Query<LocalizedService, LocalizedServicesIndex>()
.Where(s => s.Culture == Thread.CurrentThread.CurrentCulture)
.TransformWith<LocalizedServiceTransformer, LocalizedService>()
.ToList();
The indexed documents are of Type Service, and LocalizedService is a projection Type that is stored in the index.
Anyone run into this?

The .Where(...) in your case is using the standard where in "System.Linq" namespace but in order to use .TransformWith<>() you need to use the .Where(...) extension in "Raven.Client.Linq" namespace.
Make sure you have:
using Raven.Client.Linq;
in your code.

Related

How to expand(odata-webapi) all the properties without passing $expand in query string in vb.net

I am using odata v5.7.0 for webapi(vb.net).I need all the properties of object should be expanded without using $expand property on the query string.
Ex: http://localhost:26209/ProductList?$expand=customers/products
into
http://localhost:26209/ProductList
Not sure why you would want to do that and there might not be a clear cut way to achive it.Still if you want to get all the products for a customer you will have to go one at a time by using something like this.
http://localhost:26209/ProductList/customers('customer_id')/products
Else if you are using OData 2 there is an EntitySet for every association, so you an directly query the products EntitySet and use $filter instead. The URL will look similar to
http://localhost:26209/Products?$filter=CustomerId eq *
You can check $filter conventions here

Override lazy loading behavior 'lazy=false'

I would like to override the default lazy loading behavior which is set in mappings as 'lazy=false'. Can't change it as many parts of existing application depend on this setting.
After spent some hours on it I didn't find a solution so I'm asking here.
How to do this?
What I want to achieve is to fine tune my query to load only what is needed.
This is what I've tried already:
Using QueryOver api:
var properties = session.QueryOver<Property>()
.Fetch(prop => prop.Transactions).Eager
.Fetch(prop => prop.Districts).Eager
//I dont want to load those entities below so I mark
//them as lazy - IT DOESN'T WORK
//I can see in SQL that they are getting loaded in separate queries
.Fetch(prop => prop.Districts.First().Aliases).Lazy
.Fetch(prop => prop.Districts.First().PolygonPoints).Lazy
.Skip(i * pageSize)
.Take(pageSize)
.List();
Using Criteria api:
var criteria = session.CreateCriteria<Property>();
criteria.SetFetchMode("Transactions", NHibernate.FetchMode.Join);
criteria.SetFetchMode("Districts", NHibernate.FetchMode.Join);
criteria.SetFetchMode("Districts.Aliases", NHibernate.FetchMode.Select); // tried Lazy too
criteria.SetFetchMode("Districts.PolygonPoints", NHibernate.FetchMode.Select); // tried Lazy too
criteria.AddOrder(NHibernate.Criterion.Order.Asc("Id"));
criteria.SetFirstResult(i * pageSize);
criteria.SetMaxResults(pageSize);
var properties = criteria.List<Property>();
Using any of the above methods 'Aliases' and 'PolygonPoints' are always being loaded when calling List<>(). I don't need them in my process.
I'm using Nhibernate 4.0.
Any ideas?
We cannot override mapping in this case. We can do it opposite way - have lazy in place - and use eager fetching for querying.
The decision process (of reference loading) is done outside of the query, ex post. So it could be pre-loaded, but cannot be avoided.
Solution here could be of two types.
The first is preferred (by me) - do your best and make laziness the default: Ayende -
NHibernate is lazy, just live with it
Use projections. Instruct NHibernate to create just one query, use transformer to get expected object graph - without any proxies in it
There is pretty clear example how to (properly) use projection list even for references:
Fluent NHibernate - ProjectionList - ICriteria is returning null values
And we would also need Custom result transformer, which will ex-post create all the references from the returned data:
Custom DeepResultTransfomer

How does a Queryable Load work in SharePoint?

Could anybody help me to understand what kind of work is going behind the scene, when LINQ is used for retrieving SharePoint objects. For example, I can use a code like this:
private IEnumerable<List> newLists;
var dt = new DateTime(2010, 3, 20);
var query = from list
in clientContext.Web.Lists
where list.Created > dt && list.Hidden == false
select list;
newLists = clientContext.LoadQuery(query);
clientContext.ExecuteQuery();
How does it work?
How does request look like?
From documentation I found:
When you use the CSOM, you can write LINQ queries against client-side
objects, such as lists and Webs, and then use the ClientContext class
to submit these queries to the server. It's important to understand
that when you take this approach, you are using LINQ to Objects to
query SharePoint objects, not LINQ to SharePoint. This means that your
LINQ expressions are not converted to CAML and you will not see the
performance benefits that are associated with CAML conversion.
So, I was little bit confused, because I thought, that LINQ expression is transformed to Caml request. I can't understand how does it work. How can I watch details of request while executing ExecuteQuery() method? Could you please recomend me any tools for watching requests?
SP uses CAML internally: SP runtime converts Linq to CAML and send it via Soap request, or REST statement (if you are using RESTful services): http://msdn.microsoft.com/en-us/library/ff798339.aspx (with examples);
See more here:
http://msdn.microsoft.com/en-us/library/ff798464.aspx
and this can be helpful: http://nikspatel.wordpress.com/2012/08/05/sharepoint-2010-data-querying-options-server-om-vs-client-om-vs-rest-vs-linq-vs-search-api/

Can anyone explain how CDbCriteria->scopes works?

I've just checked the man page of CDbCriteria, but there is not enough info about it.
This property is available since v1.1.7 and I couldn't find any help for it.
Is it for dynamically changing Model->scopes "on-the-fly"?
Scopes are an easy way to create simple filters by default. With a scope you can sort your results by specific columns automatically, limit the results, apply conditions, etc. In the links provided by #ldg there's a big example of how cool they are:
$posts=Post::model()->published()->recently()->findAll();
Somebody is retrieving all the recently published posts in one single line. They are easier to maintain than inline conditions (for example Post::model()->findAll('status=1')) and are encapsulated inside each model, which means big transparency and ease of use.
Plus, you can create your own parameter based scopes like this:
public function last($amount)
{
$this->getDbCriteria()->mergeWith(array(
'order' => 't.create_time DESC',
'limit' => $amount,
));
return $this;
}
Adding something like this into a Model will let you choose the amount of objects you want to retrieve from the database (sorted by its create time).
By returning the object itself you allow method chaining.
Here's an example:
$last3posts=Post::model()->last(3)->findAll();
Gets the last 3 items. Of course you can expand the example to almost any property in the database. Cheers
Yes, scopes can be used to change the attributes of CDbCriteria with pre-built conditions and can also be passed parameters. Before 1.1.7 you could use them in a model() query and can be chained together. See:
http://www.yiiframework.com/doc/guide/1.1/en/database.ar#named-scopes
Since 1.1.7, you can also use scopes as a CDbCriteria property.
See: http://www.yiiframework.com/doc/guide/1.1/en/database.arr#relational-query-with-named-scopes

Unable to figure out how to do Joins within IQueryable

Here is what I am trying:
IQueryable query = this.MyRepository.GetShippingCollection();
IList<SomeListType> myList = query.Where(x => x.Settings
.Where(y => y.SelectorID.Equals(5))
.Count() > 0)
.OrderBy(x => x.Order)
.ToList();
Produces this error:
could not resolve property: Settings.ID
If I do it this way it works, but causes over 3,000 queries on my SQL Server:
IList<SomeListType> myList = this.MyRepository.GetShippingCollection().ToList();
myList = myList.Where(x => x.Settings
.Where(y => y.SelectorID.Equals(5))
.Count() > 0)
.OrderBy(x => x.Order)
.ToList();
I know the solution resides within using a "Join".
I have been looking at examples for the last couple hours and can only find Join examples within the Mapping file. I am also finding examples for "ICriteria".
I don't want to have to create seporate entries for all my complex queries in the mapping file so the join within that file will not work.
Since I am using Fluent NHibernate, I am not using "ICriteria". I am using "IQueryable". How do you join multiple tables within "IQueryable"?
Any help with this would be greatly appreciated.
Thanks in advance.
If the second query is executing 3,000 queries, it is almost certainly lazy-loading the Settings collection. As you iterate over the list, you access this collection, and each time NHibernate goes back to the database to fetch it. Try setting the fetch mode for the Settings property to eager load in the mapping.
Beyond that, the LINQ provider could be an issue. What version of NHibernate are you using? The 2.x LINQ provider has some real limitations. It has been reimplemented in the 3.0 trunk, but you'll have to download and compile it from the source.
By the way, ICriteria vs IQueryable is not related to Fluent NHibernate. Criteria API and LINQ are two providers through which you can create queries. Fluent NHibernate is an alternative way to perform configuration.