IQueryable object structure with poco generation

I created a T4 template that generates standard Entities classes along with interfaces for each of their properties, so that I can create custom poco objects containing only the data I want. I also created a copy function that can convert between any objects that implement the entity interface

The generated code is as follows:

//------------------------------------------------------------------------------ // <auto-generated> // This code was generated from a template. // // Manual changes to this file may cause unexpected behavior in your application. // Manual changes to this file will be overwritten if the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ namespace DomainModel { using System; using System.Collections.Generic; using System.Linq; public interface IRole { } public interface IRole_RoleId : IRole { int RoleId { get; set; } } public interface IRole_ApplicationName : IRole { string ApplicationName { get; set; } } public interface IRole_RoleName : IRole { string RoleName { get; set; } } public interface IRole_Description : IRole { string Description { get; set; } } public interface IRole_Users : IRole { ICollection<IUser> Users { get; set; } IUser NewUsers(); } public interface IRole__All : IRole_RoleId, IRole_ApplicationName, IRole_RoleName, IRole_Description, IRole_Users { } public partial class Role : IRole { public Role() { this.Users = new HashSet<User>(); } public int RoleId { get; set; } public string ApplicationName { get; set; } public string RoleName { get; set; } public string Description { get; set; } public virtual ICollection<User> Users { get; set; } } public static class IRoleExt { public static T CopyTo<T>(this IRole src , T dest = null ) where T : class, IRole, new() { dest = dest ?? new T(); dest.Copy(src); return dest; } public static void Copy(this IRole dest, IRole src) { var ms = new MergeStack(); Role role; if((role = dest as Role) != null){ ms.TryCopy<IRole,Role>((indexCopy) => {return indexCopy(role);}, src); } else if ((role = src as Role) != null){ ms.TryCopy<Role,IRole>((indexCopy) => {return indexCopy(dest);}, role); } else{ ms.TryCopy<IRole,IRole>((indexCopy) => {return indexCopy(dest);}, src); } dest.Copy(src, ms); } internal static void Copy(this IRole dest, IRole src, MergeStack ms) { dest.Set_RoleId(src.Get_RoleId()); dest.Set_ApplicationName(src.Get_ApplicationName()); dest.Set_RoleName(src.Get_RoleName()); dest.Set_Description(src.Get_Description()); dest.Set_Users(src.Get_Users(),ms); } public static Nullable<int> Get_RoleId(this IRole src) { IRole_RoleId srcIRole_RoleId; if((srcIRole_RoleId = src as IRole_RoleId) != null ) { return srcIRole_RoleId.RoleId; } Role role; if((role = src as Role) != null ) { return role.RoleId; } return null; } public static void Set_RoleId(this IRole dest, Nullable<int> src) { IRole_RoleId destIRole_RoleId; if((destIRole_RoleId = dest as IRole_RoleId) != null) { destIRole_RoleId.RoleId = src.GetValueOrDefault(); } Role role; if((role = dest as Role) != null ) { role.RoleId = src.GetValueOrDefault(); } } public static string Get_ApplicationName(this IRole src) { IRole_ApplicationName srcIRole_ApplicationName; if((srcIRole_ApplicationName = src as IRole_ApplicationName) != null ) { return srcIRole_ApplicationName.ApplicationName; } Role role; if((role = src as Role) != null ) { return role.ApplicationName; } return null; } public static void Set_ApplicationName(this IRole dest, string src) { IRole_ApplicationName destIRole_ApplicationName; if((destIRole_ApplicationName = dest as IRole_ApplicationName) != null) { destIRole_ApplicationName.ApplicationName = src; } Role role; if((role = dest as Role) != null ) { role.ApplicationName = src; } } public static string Get_RoleName(this IRole src) { IRole_RoleName srcIRole_RoleName; if((srcIRole_RoleName = src as IRole_RoleName) != null ) { return srcIRole_RoleName.RoleName; } Role role; if((role = src as Role) != null ) { return role.RoleName; } return null; } public static void Set_RoleName(this IRole dest, string src) { IRole_RoleName destIRole_RoleName; if((destIRole_RoleName = dest as IRole_RoleName) != null) { destIRole_RoleName.RoleName = src; } Role role; if((role = dest as Role) != null ) { role.RoleName = src; } } public static string Get_Description(this IRole src) { IRole_Description srcIRole_Description; if((srcIRole_Description = src as IRole_Description) != null ) { return srcIRole_Description.Description; } Role role; if((role = src as Role) != null ) { return role.Description; } return null; } public static void Set_Description(this IRole dest, string src) { IRole_Description destIRole_Description; if((destIRole_Description = dest as IRole_Description) != null) { destIRole_Description.Description = src; } Role role; if((role = dest as Role) != null ) { role.Description = src; } } public static ICollection<IUser> Get_Users(this Role src) { return src.Users.Cast<IUser>().ToList(); } public static ICollection<IUser> Get_Users(this IRole src) { IRole_Users srcIRole_Users; if((srcIRole_Users = src as IRole_Users) != null ) { return srcIRole_Users.Users; } Role role; if((role = src as Role) != null ) { return role.Get_Users(); } return null; } public static void Set_Users(this IRole dest, ICollection<IUser> src) { var ms = new MergeStack(); dest.Set_Users(src, ms); } internal static void Set_Users(this IRole dest, ICollection<IUser> src, MergeStack ms) { IRole_Users destIRole_Users; if((destIRole_Users = dest as IRole_Users) != null) { Func<IUser,IUser> iToIFunc = (x=> ms.TryCopy<IUser,IUser>((indexCopy)=> { var ret = destIRole_Users.NewUsers(); var exists = indexCopy(ret); if(null != exists) ret = exists; else ret.Copy(x,ms); return ret; },x)); destIRole_Users.Users = (null !=src)? src.Select(iToIFunc).ToList():null; } Role role; if((role = dest as Role) != null) { Func<IUser,User> iToEFunc = (x=> ms.TryCopy<IUser,User>((indexCopy)=> { var ret = new User(); var exists = indexCopy(ret); if(null != exists) ret = exists; else ret.Copy(x,ms); return ret; },x)); role.Users = (null !=src)? src.Select(iToEFunc).ToList():null; } } } } 

This union of the stack object you see is a tracker so that I can handle link loops. it looks like

 using System; using System.Collections.Generic; using System.Linq; namespace DomainModel { internal class MergeStack { private readonly Dictionary<Type, Dictionary<Object, Object>> _mergeObjDict = new Dictionary<Type, Dictionary<object, object>>(); private readonly IList<Action> _registerActions = new List<Action>(); public T TryCopy<TKey, T>(Func<Func<T, T>, T> func, TKey key) where T : class { if (key == null) return null; Func<T, T> act = (objToIndex) => { Dictionary<object, object> objToObj; if (!_mergeObjDict.ContainsKey(objToIndex.GetType())) { objToObj = new Dictionary<object, object>(); _mergeObjDict.Add(objToIndex.GetType(), objToObj); } else { objToObj = _mergeObjDict[objToIndex.GetType()]; } if (!objToObj.ContainsKey(key)) { objToObj.Add(key, objToIndex); } else { return objToObj[key] as T; } return null as T; }; return func(act); } } } 

Now all this works perfectly for its intended purpose, it successfully copies all implemented properties to the model and interface of the domain.

Now I'm trying to make the game enjoyable with IQueryable and lazy loading.

I'm doing it now

 dbContext.Roles.Select((x)=> x.CopyTo<RolesPoco>()); 

I would like to see if there is a way that I could automatically generate, for example

 dbContext.Roles.Select((x)=> x.Users.Include((y)=> y.someSubEntity); 

I would also like to see if I can use some suggestions like this

 //the first string is a path so something like "Roles.Users.someSubEntity" //the second string is a IQueryable function like Where or Take Dictionary<String,Dictionary<String,List<Func<T, IQueryable<TProperty>>>> queryDict dbContext.Roles.Select((x)=> x.CopyTo<RolesPoco>(queryDict) 

And then List will be a lambdas list that can work inside include functions. Anyone have any ideas on this?

Change I reorganized the simplified part of the code so that it could call getter / setter, even if the class did not implement the interface. Thus, properties can be accessed regardless of whether there is a support field. It returns null if not defined.

Edit2 . Since it seems incomprehensible to me what I'm trying to achieve, let me clarify. If you go to the notes part of this msdn page , you will see several select statements. I want to generate these expressions and then use them inside the parent selection depending on whether the class that contains the interface that implements this element is copied. I avoid linqToObject because I only need the properties defined in CopyTo, but the Navigation properties are interfaces that explode the structure of the entity. This is for Lazy boot purposes. MergeStack will compose and return these expressions up the tree. I got an idea from the DaedTech email blog.

+6
source share
1 answer

IQueryable roles, so you need to get the Select method from the Queryable extensions class. You also need to get Include from the Enumerable extension class. Then you need to call the Select method using Role as a general argument. You need to build lambda using Expression.Lambda, Expression.Call and Expression.Property.

0
source

All Articles