How to retrieve unique entities through NHibernate Criteria API? - nhibernate

My entities look something like that (simplified):
public class Person
{
public Guid Id { get; set; }
public string Name { get; set; }
public IList<Department> Departments { get; set; }
}
public class Department
{
public Guid Id { get; set; }
public string Name { get; set; }
}
I'm querying the database through criteria api for all persons that have a department with a certain name that should match a like-pattern.
It happens that a person contains two or more departments whose names contain the same character sequence which is used by the query. Therefore the same person is returned multiple times. To surpress this, I know that I can use criteria.SetResultTransformer(Transformers.DistinctRootEntity); but this works only as long as the result is not paged.
When I'm paging the result I don't only need to get the first page but I also need to know how many entities there are in total. Unfortunately the result transformer does not work when calling criteria.SetProjection(Projections.RowCount()) as there is no result to be transformed.
Can I somehow avoid retrieving the whole list of person with the result transformer and then manually taking the right part out of the collection?
Best Regards
Oliver Hanappi

You need to include distinct in your sql request. Some information you can find here. Second answer mostly

Related

Entity Framework Core Code First Model Navidation Properties

I have a Web API that uses entity framework. I have several tables there were created using the code first setup. My Competitions class is defined below.
Everything works great and I'm able to get my Competitions table data along with all the data in the navigation properties that are returning a collection. However, I'm not able to get any values for the CompetitionTypes and Users navigation properties. OwnerId references UserId in the Users table.
How would I get the linked data in my CompetitionTypes and Users table? I basically want the same thing as the three collection navigation properties, except that CompetitionTypes and Users would only return one row.
public partial class Competitions
{
[Key, Required]
public int CompetitionId { get; set; }
public int CompetitionTypeId { get; set; }
public int OwnerId { get; set; }
public string CompetitionName { get; set; }
public CompetitionTypes CompetitionTypeId { get; set; }
public Users UserId { get; set; }
public ICollection<Participants> Participants { get; set; }
public ICollection<ResultStats> ResultStats { get; set; }
public ICollection<Results> Results { get; set; }
}
}
EF auto-matches FK properties with navigation properties based on conventions. Namely, it expects FK properties to be named the same as navigation properties, just with Id at the end. In other words, for it to automatically match up OwnerId, you'd need a navigation property like:
public User Owner { get; set; }
Since your navigation property is UserId, it's actually looking for a property named UserIdId.
If you don't want to follow conventions, then you must either use the ForeignKey attribute or fluent config to tell EF which property belongs with which.
That said, there's some pretty major issues with your naming of things here. First, entities should always be singular User, not Users. Second, you should not have navigation properties that end with Id: e.g., User, not UserId. Only actual PK or FK properties should end with with Id. Finally, don't prefix properties on your entity with the entity name. This last one is mostly for readability. Which is more natural: competition.Id or competition.CompetitionId? Likewise with CompetitionName; it should just be Name. And, for what it's worth, you don't need Required for either a primary key or a non-nullable type (such as int). In either case, the property is required by default.

What are the steps for building a faceted search solution with RavenDB?

I need to build a new search solution for our website that will allow users to quickly locate products that match their needs. We want to use a faceted "Amazon.com" type of search and I want to implement using RavenDB. Can anyone help me with defining at a high-level what the steps are to accomplish this from beginning to end. I have already figured out a few of them and I have also determined that I am going to have to make use of Dynamic Fields. So here are the steps that I know of. Any advice/direction/clarification would be greatly appreciated.
Download and install RavenDB
Setup the RavenDB Server (I have chosen to run under IIS)
Create object(s) to store data. I know I am going to need to make use of Dynamic Fields since products can have different attributes. My current objects look like this:
public class ProductSeries
{
public Guid UID { get; set; }
public String SeriesName { get; set; }
public String SeriesDescription { get; set; }
public String ProductIDInCMS { get; set; }
public List<ProductAttribute> Attributes { get; set; }
}
public class ProductAttribute
{
public string Attribute { get; set; }
public string Value { get; set; }
}
Store documents in database.
Create indexes??? Here's where I get lost. Is this the next step?
...
???
Ultimately, I know I will conclude with creating some sort of AJAX enabled control that will display facets with their values and counts and allow users to make selections that will filter our thousands of products down to a select few that meet their criteria. I think I know where I start and where I finish; it's what happens in between that has me stumped.
Did you read the docs about this?
They explain all of it: http://ravendb.net/docs/2.5/client-api/faceted-search

RavenDB Modeling - a single document vs multiple documents?

Given a simple example as follows, I'd like some guidance on whether to store as a single document vs multiple documents.
class User
{
public string Id;
public string UserName;
public List<Post> Posts;
}
class Post
{
public string Id;
public string Content;
}
Once the data is stored, there are times when I will want all the posts for a given user. Sometimes I might want posts across multiple users that meet a particular criteria.
Should I store each User as a document (with Posts embedded), or does it make more sense to store Users and Posts as seperate documents, and have some sort of ID in my post to link it back to a User?
Now, what if each user belonged to an Organization (there will be hundreds of organizations in my application)?
class Organization
{
public string Id;
public List<User> users;
}
Should I then stay with the single document approach? In this case I would store one giant document for each organization, which will contain embedded users, which in turn contain embedded posts?
You should keep them as separate documents. User, Organization, and Post are great examples of aggregate entities, and in Raven, each aggregate is usually its own document.
Only entities which are not aggregates should be nested in the same document. For example, in Post you might have a List<Comment>. Comment and Post are both entities, but only Post is an aggregate.
You should instead model them with references:
public class User
{
public string Id { get; set; }
public string Name { get; set; }
public List<string> PostIds { get; set; }
}
public class Post
{
public string Id { get; set; }
public string Content { get; set; }
}
public class Organization
{
public string Id { get; set; }
public List<string> UserIds { get; set; }
}
Optionally, you can denormalize some of the data into your references where appropriate:
public class UserRef
{
public string Id { get; set; }
public string Name { get; set; }
}
public class Organization
{
public string Id { get; set; }
public List<UserRef> Users { get; set; }
}
Denormalizing the user's name into the organization document has the benefit of not needing to fetch each user document when displaying the organization. However, it has the drawback of having to update the organization document any time a user's name is changed. You should weigh the pros and cons of this each time you consider a relationship. There is no one right answer for all cases.
Also, you should be considering how data will be really used. In practice, you will probably find that your Organization class may not need a user list at all. Instead, you could put a string OrganizationId property on the User class. That would be easier to maintain, and if you wanted a list of users in an organization, you could query for that information using an index.
You should read more in the raven documentation on Document Structure Design and Handling Document Relationships.

Returning Custom Data WCF

I am new to WCF and am looking for some advice on a particular problem. I am using Enitity Framework and am wanting to return my entities as JSON through WCF. However I am only wanting to return certain information in certain circumstances. For example in one method I might want to return a users username along with their userid, in another instance I want to return a users username, userid and telephone number. Initially I thought maybe I could return an anonymous type such as
var obj = new { username = user.UserName, userid = user.UserId };
But after researching I found out that was not a good idea. I then thought of returning a Dictionary of key values, the problem with that approach is the JSON that is returned:
{"key":"username","Value":"Andrew"}
I am after something along the lines of
{"username":"Andrew"}
I have also though of making my own types. Is there a way to exclude properties? i.e. If my type has a property Telephone will I be able to exclude it in certain circumstances?
Any help / suggestions much appreciated
I know in DataContractSerializer, you can use EmitDefaultValue, for example, you can have a contract named UserInfo
[DataContract]
public class UserInfo
{
[DataMember]
public string UserID { get; set; }
[DataMember]
public string UserName { get; set; }
[DataMember(EmitDefaultValue=false)]
public int Age { get; set; }
[DataMember(EmitDefaultValue=false)]
public DateTime Time { get; set; }
}
I don't know whether EmitDefaultValue is supported by the JSON serializer, can you try it by yourself?

Fluent nHibernate some kind of flat table

i have one problem (obviously :) )
Is it possible to make dynamic queries in nHibernate in that way...
I have many tables (let we say: User, City, Country, Continet,...) is it possible to flaten this data so i do not need to know joins between this tables (get continent for user, without making join user.city, city.country, coutry.continent)?
The point is i want to some kind flatten data, so user can dynamically select data on user interface without knowing data model behind application?
It will be great that someone gave me at least idea how to make this, or if it's possible...
One example on web is GoogleAnalytics Custom reports (you can drag dimensions and metrics on UI and get results)
You said you're using Fluent NHibernate, which means that, assuming your domain model is structured correctly, you should not need to use any joins.
"Flattening" the data is a UI concern, not a database concern, so you shouldn't flatten your data model or simplify it for the UI unless you absolutely have to.
Let's assume you have the following entities:
public class User
{
public virtual string Name { get; set; }
public virtual City City { get; set; }
}
public class City
{
public virtual string Name { get; set; }
public virtual Country { get; set; }
}
public class Country
{
public virtual string Name { get; set; }
}
If you want to filter users by a certain country, the LINQ query for this (assuming NHibernate 3) would be:
var country = session.Single<Country>(x => x.Name == "Africa");
session.Query<User>().Where(x => x.City.Country == country);