Created
November 6, 2014 03:39
-
-
Save jeremylcarter/f9ffce5979d9d9036faa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ColumnInfo { | |
... | |
... | |
... | |
public bool OneToOneColumn { get; set; } | |
public bool OneToManyColumn { get; set; } | |
public bool LazyLoad { get; set; } | |
public static ColumnInfo FromMemberInfo(MemberInfo mi) | |
{ | |
var ci = new ColumnInfo(); | |
var attrs = mi.GetCustomAttributes(true); | |
var colAttrs = attrs.OfType<ColumnAttribute>(); | |
var columnTypeAttrs = attrs.OfType<ColumnTypeAttribute>(); | |
var ignoreAttrs = attrs.OfType<IgnoreAttribute>(); | |
var oneToOne = attrs.OfType<OneToOneAttribute>(); | |
var oneToMany = attrs.OfType<OneToManyAttribute>(); | |
// Check if declaring poco has [ExplicitColumns] attribute | |
var explicitColumns = mi.DeclaringType.GetCustomAttributes(typeof(ExplicitColumnsAttribute), true).Any(); | |
var aliasColumn = (AliasAttribute) mi.GetCustomAttributes(typeof (AliasAttribute), true).FirstOrDefault(); | |
// Ignore column if declarying poco has [ExplicitColumns] attribute | |
// and property doesn't have an explicit [Column] attribute, | |
// or property has an [Ignore] attribute | |
if ((explicitColumns && !colAttrs.Any()) || ignoreAttrs.Any()) | |
{ | |
ci.IgnoreColumn = true; | |
} | |
// Try to detect relationship columns | |
try | |
{ | |
if (oneToOne != null && !colAttrs.Any() && oneToOne.Any()) | |
{ | |
if (oneToOne.FirstOrDefault() != null) | |
{ | |
ci.ForeignKeyName = oneToOne.FirstOrDefault().Column; | |
} | |
if (oneToOne.FirstOrDefault().LazyLoad == true) | |
{ | |
ci.LazyLoad = true; | |
} | |
ci.IgnoreColumn = true; | |
ci.OneToOneColumn = true; | |
} | |
if (oneToMany != null && !colAttrs.Any() && oneToMany.Any()) | |
{ | |
if (oneToMany.FirstOrDefault() != null) | |
{ | |
ci.ForeignKeyName = oneToMany.FirstOrDefault().Column; | |
} | |
if (oneToMany.FirstOrDefault().LazyLoad == true) | |
{ | |
ci.LazyLoad = true; | |
} | |
ci.IgnoreColumn = true; | |
ci.OneToManyColumn = true; | |
} | |
} | |
catch (Exception) | |
{ | |
} | |
// Read attribute | |
if (colAttrs.Any()) | |
{ | |
var colattr = colAttrs.First(); | |
ci.ColumnName = colattr.Name ?? mi.Name; | |
ci.ForceToUtc = colattr.ForceToUtc; | |
ci.ResultColumn = colattr is ResultColumnAttribute; | |
ci.VersionColumn = colattr is VersionColumnAttribute; | |
ci.ComputedColumn = colattr is ComputedColumnAttribute; | |
ci.ColumnAlias = aliasColumn != null ? aliasColumn.Alias : null; | |
} | |
else | |
{ | |
ci.ColumnName = mi.Name; | |
} | |
if (columnTypeAttrs.Any()) | |
{ | |
ci.ColumnType = columnTypeAttrs.First().Type; | |
} | |
return ci; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public List<T1> FetchAndInclude<T1>(Expression<Func<T1, bool>> expression, bool lazyLoad = true) | |
{ | |
if (this.LazyLoading | lazyLoad) | |
{ | |
var pd = PocoDataFactory.ForType(typeof(T1)); | |
var members = pd.RelationshipColumns; | |
if (members.Count != 0 && members.Count(i => i.Value.LazyLoad) != 0) | |
{ | |
return FetchAndInclude<T1>(expression, members.Select(i => i.Value.ColumnType)); | |
} | |
} | |
return FetchWhere<T1>(expression); | |
} | |
internal List<T1> FetchAndInclude<T1, T2>(string sql, object[] para) | |
{ | |
var pd = PocoDataFactory.ForType(typeof(T1)); | |
var members = pd.RelationshipColumns; | |
if (members.Count != 0) | |
{ | |
var resultSet = Fetch<T1>(sql,para); | |
if (resultSet != null && members.Any()) | |
{ | |
foreach (var member in members) | |
{ | |
var relationshipColumn = member.Value; | |
var foreignKey = relationshipColumn.ForeignKeyName; | |
// cache the underlying type from the database | |
Dictionary<object, T2> itemCache = new Dictionary<object, T2>(); | |
foreach (var resultItem in resultSet) | |
{ | |
try | |
{ | |
var foreignKeyObject = resultItem.GetProperty(foreignKey); | |
if (foreignKeyObject != null) | |
{ | |
if (!itemCache.ContainsKey(foreignKeyObject)) | |
{ | |
var resultQuery = SingleOrDefaultById<T2>(foreignKeyObject); | |
itemCache.Add(foreignKeyObject, resultQuery); | |
relationshipColumn.SetValue(resultItem, resultQuery); | |
} | |
else | |
{ | |
relationshipColumn.SetValue(resultItem, itemCache[foreignKeyObject]); | |
} | |
} | |
} | |
catch (Exception) | |
{ | |
} | |
} | |
itemCache.Clear(); | |
itemCache = null; | |
} | |
} | |
return resultSet; | |
} | |
return Fetch<T1>(sql, para); | |
} | |
private List<T1> FetchAndInclude<T1>(Expression<Func<T1, bool>> expression, IEnumerable<Type> types) | |
{ | |
if (types != null && types.Any()) | |
{ | |
var pd = PocoDataFactory.ForType(typeof(T1)); | |
var members = pd.RelationshipColumns.Where(i => i.Value.ColumnType.In(types)); | |
List<T1> resultSet = null; | |
if (expression == null) | |
{ | |
resultSet = Fetch<T1>(); | |
} | |
else | |
{ | |
resultSet = FetchWhere<T1>(expression); | |
} | |
if (resultSet != null) | |
{ | |
foreach (var member in members) | |
{ | |
try | |
{ | |
var memberType = member.Value.ColumnType; | |
var relationshipColumn = member.Value; | |
var foreignKey = relationshipColumn.ForeignKeyName; | |
// cache the underlying type from the database | |
Dictionary<object, object> itemCache = new Dictionary<object, object>(); | |
foreach (var resultItem in resultSet) | |
{ | |
try | |
{ | |
if (!member.Value.IsGeneric) | |
{ | |
var foreignKeyObject = resultItem.GetProperty(foreignKey); | |
if (foreignKeyObject != null) | |
{ | |
if (!itemCache.ContainsKey(foreignKeyObject)) | |
{ | |
MethodInfo method = GetType().GetMethod("SingleOrDefaultById") | |
.MakeGenericMethod(new Type[] {memberType}); | |
var resultQuery = method.Invoke(this, new object[] {foreignKeyObject}); | |
itemCache.Add(foreignKeyObject, resultQuery); | |
relationshipColumn.SetValue(resultItem, resultQuery); | |
} | |
else | |
{ | |
relationshipColumn.SetValue(resultItem, itemCache[foreignKeyObject]); | |
} | |
} | |
} | |
else | |
{ | |
var foreignKeyObject = resultItem.GetProperty(pd.TableInfo.PrimaryKey); | |
if (foreignKeyObject != null) | |
{ | |
if (!itemCache.ContainsKey(foreignKeyObject)) | |
{ | |
// Enumerable | |
var baseType = member.Value.ColumnType.GetGenericArguments()[0]; | |
var md = PocoDataFactory.ForType(baseType); | |
List<MethodInfo> methods = | |
GetType() | |
.GetMethods() | |
.Where(i => i.Name == "Fetch") | |
.Where(m => m.GetGenericArguments().Length == 1) | |
.Where(m => m.GetParameters().Length == 2).ToList(); | |
var method = | |
methods.FirstOrDefault().MakeGenericMethod(new Type[] {baseType}); | |
var sqlSelect = AutoSelectHelper.SimpleSelect(this, md, foreignKey, | |
foreignKeyObject); | |
var resultQuery = method.Invoke(this, new object[] {sqlSelect, null}); | |
itemCache.Add(foreignKeyObject, resultQuery); | |
relationshipColumn.SetValue(resultItem, resultQuery); | |
} | |
else | |
{ | |
relationshipColumn.SetValue(resultItem, itemCache[foreignKeyObject]); | |
} | |
} | |
} | |
} | |
catch (Exception) | |
{ | |
} | |
} | |
itemCache.Clear(); | |
itemCache = null; | |
} | |
catch (Exception) | |
{ | |
} | |
} | |
} | |
return resultSet; | |
} | |
return FetchWhere<T1>(expression); | |
} | |
public List<T1> FetchAndInclude<T1, T2>(Expression<Func<T1, bool>> expression) | |
{ | |
var pd = PocoDataFactory.ForType(typeof(T1)); | |
var members = pd.RelationshipColumns; | |
if (members.Count != 0) | |
{ | |
var resultSet = FetchWhere<T1>(expression); | |
if (resultSet != null && members.Any()) | |
{ | |
foreach (var member in members) | |
{ | |
var relationshipColumn = member.Value; | |
var foreignKey = relationshipColumn.ForeignKeyName; | |
// cache the underlying type from the database | |
Dictionary<object, T2> itemCache = new Dictionary<object, T2>(); | |
foreach (var resultItem in resultSet) | |
{ | |
try | |
{ | |
var foreignKeyObject = resultItem.GetProperty(foreignKey); | |
if (foreignKeyObject != null) | |
{ | |
if (!itemCache.ContainsKey(foreignKeyObject)) | |
{ | |
var resultQuery = SingleOrDefaultById<T2>(foreignKeyObject); | |
itemCache.Add(foreignKeyObject, resultQuery); | |
relationshipColumn.SetValue(resultItem, resultQuery); | |
} | |
else | |
{ | |
relationshipColumn.SetValue(resultItem, itemCache[foreignKeyObject]); | |
} | |
} | |
} | |
catch (Exception) | |
{ | |
} | |
} | |
itemCache.Clear(); | |
itemCache = null; | |
} | |
} | |
return resultSet; | |
} | |
return FetchWhere<T1>(expression); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public Dictionary<string, RelationshipColumn> RelationshipColumns { get; protected internal set; } | |
public PocoData(Type t, IMapper mapper) | |
: this() | |
{ | |
.... .... | |
.... | |
.... | |
RelationshipColumns = new Dictionary<string, RelationshipColumn>(StringComparer.OrdinalIgnoreCase); | |
ColumnInfo ci = ColumnInfo.FromMemberInfo(mi); | |
if (ci.IgnoreColumn) | |
{ | |
if (ci.LazyLoad | ci.OneToManyColumn | ci.OneToOneColumn) | |
{ | |
// Relationship column | |
var rc = new RelationshipColumn(); | |
rc.TableInfo = TableInfo; | |
rc.MemberInfo = mi; | |
rc.ColumnName = ci.ColumnName; | |
rc.ForeignKeyName = ci.ForeignKeyName; | |
rc.ResultColumn = ci.ResultColumn; | |
rc.ComputedColumn = ci.ComputedColumn; | |
rc.ColumnType = ci.ColumnType; | |
rc.ColumnAlias = ci.ColumnAlias; | |
rc.LazyLoad = ci.LazyLoad; | |
rc.IsOneToMany = ci.OneToManyColumn; | |
rc.IsOneToOne = ci.OneToOneColumn; | |
try | |
{ | |
if (mi.ReflectedType != null) | |
{ | |
if (mi.GetMemberInfoType().IsGenericType || | |
mi.GetMemberInfoType().GetGenericTypeDefinition() == typeof (IEnumerable<>)) | |
{ | |
rc.IsGeneric = true; | |
} | |
} | |
} | |
catch (Exception) | |
{ | |
} | |
RelationshipColumns.Add(rc.ColumnName, rc); | |
} | |
continue; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] | |
public class RelationshipAttribute : Attribute | |
{ | |
public RelationshipAttribute(string column = "Id", bool lazyLoad = false) | |
{ | |
Column = column; | |
LazyLoad = lazyLoad; | |
} | |
public bool LazyLoad { get; set; } | |
public string Column { get; set; } | |
} | |
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] | |
public class OneToOneAttribute : RelationshipAttribute | |
{ | |
public OneToOneAttribute(string column = "Id", bool lazyLoad = false) | |
{ | |
Column = column; | |
LazyLoad = lazyLoad; | |
} | |
} | |
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] | |
public class OneToManyAttribute : RelationshipAttribute | |
{ | |
public OneToManyAttribute(string column = "Id", bool lazyLoad = false) | |
{ | |
Column = column; | |
LazyLoad = lazyLoad; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment