views:

25

answers:

2

I have an existing view which has too much data in it. Unfortunately I cannot get rid of it so I need to try to work around it using my NHibernate mapping. The idea is to have NH issue the following query:

SELECT DISTINCT User_Id, Module_Id, Application_Id, RightsMask
FROM V_UserApplicationPermissions
WHERE User_Id = ?

My current mapping for this list of AccessControlEntry types looks like this:

HasMany<AccessControlEntry>(x => x.Rights)
    .WithTableName("V_UserApplicationPermissions")
    .KeyColumnNames.Add("User_Id")
    .Component(c =>
    {
        c.Map(x => x.Module, "Module_Id");
        c.Map(x => x.Application, "App_Id");
        c.Map(x => x.Rights, "RightsMask").CustomTypeIs<ApplicationRightsType>();
    })
    .Not.LazyLoad();

Any thoughts on how to have NHibernate put a DISTINCT keyword in there during the query?

UPDATE: Let me share the rest of the User map that might help as to why it isn't a straight forward criteria:

WithTable("Users");
Id(x => x.Id, "UserId");
Map(x => x.Name, "UserName");
HasMany<long>(x => x.Clients)
    .WithTableName("V_UserClients")
    .KeyColumnNames.Add("UserId")
    .AsElement("ClientId");
+1  A: 

Use one of these:

session.CreateCriteria(typeof(AccessControlEntry)
        .Add(...)
        .SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer())

or

    criteria.SetProjection(Projections.Distinct(Projections.Property("User_Id")));

//add projections for other fields...
Module_Id
Application_Id
RightsMask
igor
So what you are saying is to do it in the retrieve, not in the mapping?
Colin Bowern
Just use this code to retrive. It is not mapping.
igor
Doesn't appear to work in the broader picture of the entire map. AccessControlEntity is a property of the larger object User. How can I query for user with the ID 1234 and tell it only to grab distinct rights entries?
Colin Bowern
1)Have you caught the db sql select, that was generated by your nhibernate request? 2) Why don't you use the stored proc? I did something with permissions some months ago. I think, T-SQL is better to do so "db things". Than map your entity to result of this sp. It easier and has better performance.
igor
A: 

Olivier Coanet from the NHUsers mailing list suggested hacking it into the WithTableName which worked:

HasMany<AccessControlEntry>(x => x.Rights)  
    .WithTableName("(SELECT DISTINCT User_Id, Module_Id, App_Id, RightsMask FROM V_UserApplicationPermissions)")  
    .KeyColumnNames.Add("User_Id")  
    .Component(c =>  
    {  
        c.Map(x => x.Module, "Module_Id");  
        c.Map(x => x.Application, "App_Id");  
        c.Map(x => x.Rights, "RightsMask").CustomTypeIs<ApplicationRightsType>();  
    })  
Colin Bowern

related questions