Running some code after an entity is loaded

Posts   
 
    
worldspawn avatar
worldspawn
User
Posts: 321
Joined: 26-Aug-2006
# Posted on: 10-Jan-2011 04:54:50   

Hello,

I am joining a list onto another list (with LINQ):


var test = (from l in meta.User
                        join cp in meta.ContextPermissions on new { EntityId = l.Id, EntityType = "User" } equals new { EntityId = cp.EntityId, EntityType = cp.EntityType }
                        where (((int)cp.Permission & (int)1) == (int)1)
                        select new EP { EntityId = l.Id, Permission = cp.Permission.GetValueOrDefault() }).Distinct().ToList();

I'd like to change this query so it just returns an IQuerable<UserEntity> however I need to capture somewhere the values in cp (like Permission, EntityId). I was wondering if the linq provider would even create an instance of ContextPermissionsEntity in a scenario like this but it appears it does. I have tried overriding some methods like "OnInitialized" or "OnInitClassMembersComplete" and I also tried creating an Auditor for the LoadOfEntity. The auditor for some reason never seems to have AuditLoadOfEntity called and the other methods are called however the values of the fields have not been set.

So I was wondering if there was a override/hook somewhere I can intercept the loading of these ContextPermissionEntities after their values are set and cache their values.

worldspawn avatar
worldspawn
User
Posts: 321
Joined: 26-Aug-2006
# Posted on: 10-Jan-2011 06:39:07   

Something else, I wanted to abstract a join on my query away.


public static IQueryable<EP> Test<T, CP>(string entityType, IQueryable<CP> cplist, IQueryable<T> list) where T : IShivamEntity where CP : IContextPermission
        {
            var result = list.Join(cplist.Where(p=>(p.Permission & 1) == 1), p => p.Id, p => p.EntityId, (u, cp) => new EP { EntityId = u.Id, Permission = cp.Permission.GetValueOrDefault() });
            return result;
        }

This fails. If I write the exact same line with strong types it works fine. I believe this fails because the MemberInfo for Init expression (and the cplist where clause) are pointing to the interface members and not the entity members.

Would this work if the MemberInfos were swapped to the properties form the entity classes? Any hints on how I could do this...?

Forgetting the where clause for a moment, I have my member init defined lile this:


System.Linq.Expressions.Expression<Func<T, CP, EP>> test = (u, cp) => new EP { EntityId = u.Id, Permission = cp.Permission.GetValueOrDefault() };

Then:

var initExpr = (((System.Linq.Expressions.MemberInitExpression)test.Body);

Here's where I'm getting confused on how to remake the binding expression:


var idBinding = Expression.Bind(
            ((System.Linq.Expressions.MemberAssignment)initExpr.Bindings[0]).Member,
             Expression.MakeMemberAccess()//think i need a new member access here pointing to the entity classes id property rather than the interfaces id property.
            )

I'm using llbl 3.

If my initial query is in linq is there some way to tap into the provider to get the generated relation predicate bucket and add to it (mix linq with llbl query types). I ask this because obviously what I am trying to do doesn't lend itself well to llbl linq, however I still want to write my main queries in linq.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 10-Jan-2011 08:10:56   

You should have created 2 diferent threads, for these different issues.

I am joining a list onto another list (with LINQ):

Code:

var test = (from l in meta.User join cp in meta.ContextPermissions on new { EntityId = l.Id, EntityType = "User" } equals new { EntityId = cp.EntityId, EntityType = cp.EntityType } where (((int)cp.Permission & (int)1) == (int)1) select new EP { EntityId = l.Id, Permission = cp.Permission.GetValueOrDefault() }).Distinct().ToList();

I'd like to change this query so it just returns an IQuerable<UserEntity> however I need to capture somewhere the values in cp (like Permission, EntityId). I was wondering if the linq provider would even create an instance of ContextPermissionsEntity in a scenario like this but it appears it does. I have tried overriding some methods like "OnInitialized" or "OnInitClassMembersComplete" and I also tried creating an Auditor for the LoadOfEntity. The auditor for some reason never seems to have AuditLoadOfEntity called and the other methods are called however the values of the fields have not been set.

So I was wondering if there was a override/hook somewhere I can intercept the loading of these ContextPermissionEntities after their values are set and cache their values.

If you want to fetch a Graph of Users and their ContextPermissions, then you need to use PrefetchPaths.

worldspawn avatar
worldspawn
User
Posts: 321
Joined: 26-Aug-2006
# Posted on: 10-Jan-2011 10:22:08   

You should have created 2 diferent threads, for these different issues.

Sorry. http://llblgen.com/TinyForum/Messages.aspx?ThreadID=19234

If you want to fetch a Graph of Users and their ContextPermissions, then you need to use PrefetchPaths.

My purpose is two fold. First is yes to have the ContextPermissions available, second though is by joining onto them to exclude the results where there is no permission assigned. Is what I asked not possible? The object appears to be instantiated I just can't see if it's populated at any stage.

I have no FK between a given table and the ContextPermissions view so unless I manually create a FK for all my secured entities I think that means I can't use prefetch paths.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 10-Jan-2011 15:30:32   

You may use the Designer to define a custom relation between Users & ContextPermissions. And then you would get PrefetchPaths from Users to ContextPermissions generated in code.

Having PrefetchPaths ready for use, you can specify a PrefetchPath to fetch the ContextPermissions in the same graph associated to the User. This won't prevent you from joining to ContextPermissions to use it for filtering when you query for Users.