public static Tables.View LoadView(Type type) { if (_viewCache == null) { _viewCache = new Dictionary <Type, Tables.View>(); } if (!_viewCache.ContainsKey(type)) { object[] attrs = type.GetCustomAttributes(typeof(Attributes.View), true).ToArray(); if (attrs != null) { Tables.View view = new Tables.View(); foreach (Attributes.View attr in attrs) { var tableLeft = attr.ModelLeft != null?LoadTable(attr.ModelLeft) : null; var tableRight = attr.ModelRight != null?LoadTable(attr.ModelRight) : null; if (tableLeft != null && tableRight != null) { var fieldLeft = (attr.ModelProperyLeft is string) ? tableLeft.GetFieldByPropertyName((string)attr.ModelProperyLeft) : null; var fieldRight = (attr.ModelProperyRight is string) ? tableRight?.GetFieldByPropertyName((string)attr.ModelProperyRight) ?? null : null; if (fieldLeft != null || fieldRight != null) { var joinType = JoinType.Cross; switch (attr.Connect) { case Attributes.ViewConnect.Check: joinType = JoinType.LeftOuter; break; case Attributes.ViewConnect.CheckExisting: joinType = JoinType.Inner; break; } Conditions.Condition cond = null; if (fieldLeft != null && fieldRight != null) { cond = Conditions.Condition.AndField(tableLeft.Name + "." + fieldLeft.Name, tableRight.Name + "." + fieldRight.Name); } else if (fieldLeft != null && fieldRight == null) { cond = Conditions.Condition.AndValue(tableLeft.Name + "." + fieldLeft.Name, attr.ModelProperyRight); } else if (fieldLeft == null && fieldRight != null) { cond = Conditions.Condition.AndValue(tableRight.Name + "." + fieldRight.Name, attr.ModelProperyLeft); } if (cond != null) { view.AddJoin(Join.Create(tableLeft.Name, tableRight.Name, cond, joinType)); } } } foreach (var field in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) { object[] fieldAttrs = field.GetCustomAttributes(typeof(Attributes.ViewField), true); if (fieldAttrs != null && fieldAttrs.Any()) { foreach (Attributes.ViewField fieldAttr in fieldAttrs) { var table = LoadTable(fieldAttr.ModelType); if (table != null) { string name = !string.IsNullOrEmpty(fieldAttr.ModelProperyName) ? fieldAttr.ModelProperyName : field.Name; if (_fieldsCache.ContainsKey(type) && _fieldsCache[type].Any(x => x.Name == name)) { view.AddField(table.Name, table.Type, _fieldsCache[type].FirstOrDefault(x => x.Name == name)); } else { var tableField = table.GetFieldByPropertyName(fieldAttr.ModelProperyName); if (tableField != null) { string tableFieldName = null; if (fieldAttr is Attributes.AggregateField) { tableFieldName = tableField.Name; var functionField = FunctionField.CreateFunctionAggregateField(field, (Attributes.AggregateField)fieldAttr, tableField); if (functionField != null) { tableFieldName += functionField.Name; tableField = functionField; } view.AddField(table.Name, table.Type, tableField, tableField.Name); } else { var loadedFields = LoadField(tableField.Property); foreach (var loadField in loadedFields) { loadField.Property = field; view.AddField(table.Name, table.Type, loadField); } } } } } } } } } if (view.Tables != null) { _fieldsCache.Add(type, view.Tables.SelectMany(x => x.Fields.Values).ToArray()); _viewCache.Add(type, view); } else { return(null); } } else { throw new Exceptions.TableAttributeException("No view attributes in type"); } } return(_viewCache[type]); }