/// <summary> /// Specifies the foreign key that is to be used in relation. /// The foreign key should be explicitly given when there is more than one relation between two tables. /// </summary> /// <typeparam name="T">The type of the node.</typeparam> /// <param name="node">The node to which belongs the foreign key.</param> /// <param name="column">The column that is part of the foreign key.</param> public static DbTable <T> By <T>(this DbTable <T> node, string column) where T : DbRow { // null check if (node == null) { throw new QueryTalkException(".By", QueryTalkExceptionType.ArgumentNull, "node", Text.Method.By); } if (column == null) { throw new QueryTalkException(".By", QueryTalkExceptionType.ArgumentNull, "column", Text.Method.By); } var nodeMap = DbMapping.GetNodeMap(node.NodeID); ColumnMap columnMap = null; foreach (var col in nodeMap.Columns) { if (Api.IsEqual(col.Name.Part1, column)) { columnMap = col; break; } } if (columnMap == null) { throw new QueryTalkException(".By", QueryTalkExceptionType.ColumnNotFound, String.Format("node = {0}{1} column = {2}", node.Name, Environment.NewLine, column), Text.Method.By) .SetObjectName(node.Name); } ((IRelation)node).FK = columnMap.ID; return(node); }
internal static DataTable ToDataTable <U>(IEnumerable <U> collection) { string collectionTypeName; Type tableType = typeof(U); if (collection == null) { throw new QueryTalkException("ToDataTable<T>", QueryTalkExceptionType.CollectionNullOrEmpty, String.Format("data class = {0}", tableType), Text.Method.ToDataTable); } collectionTypeName = collection.GetType().Name; if (collection is Wall.IResult) { collectionTypeName = Text.Class.ResultSet; } if (collectionTypeName == Text.Class.ResultSet) { var resultSet = (ResultSet <U>)collection; if (resultSet.DataTable != null) { return(resultSet.DataTable); } // check dynamic - not convertable if (tableType == typeof(System.Object)) { if (collection.Count() == 0) { throw new QueryTalkException("ResultSet.getTableType", QueryTalkExceptionType.EmptyResultset, "table type = dynamic", Text.Method.ToDataTable); } // infer type from the item using (var enumerator = collection.GetEnumerator()) { enumerator.MoveNext(); tableType = enumerator.Current.GetType(); } } } DataTable dataTable = new DataTable(); dataTable.Locale = System.Globalization.CultureInfo.InvariantCulture; // always build new getters (not using cache) var getters = new List <IPropertyAccessor>(); var props = tableType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Where(prop => prop.GetGetMethod() != null) .ToArray(); PropertyInfo[] properties; if (tableType.IsDbRow()) { var node = DbMapping.GetNodeMap(tableType); var propsByDatabaseOrder = new List <PropertyInfo>(); foreach (var column in node.SortedColumnsByDatabaseOrder) { var prop = props.Where(a => a.Name.EqualsCS(column.ClrName)).Select(a => a).FirstOrDefault(); if (prop != null) { propsByDatabaseOrder.Add(prop); } } properties = propsByDatabaseOrder.ToArray(); } else { properties = props; } if (properties.Length == 0) { throw new QueryTalkException("ResultSet.ToDataTable", QueryTalkExceptionType.InvalidDataClass, String.Format("data class = {0}", tableType), Text.Method.ToDataTable); } int numberOfPropertiesUsed = 0; foreach (PropertyInfo property in properties) { Type clrType; QueryTalkException exception; var clrTypeMatch = Mapping.CheckClrCompliance(property.PropertyType, out clrType, out exception); if (clrTypeMatch == Mapping.ClrTypeMatch.NodeMatch) { continue; } if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch) { ThrowNotClrCompliantException(exception, property.PropertyType); } dataTable.Columns.Add(property.Name, clrType); getters.Add(PropertyAccessor.Create(tableType, property)); ++numberOfPropertiesUsed; } foreach (U item in collection) { DataRow row = dataTable.NewRow(); for (int i = 0; i < numberOfPropertiesUsed; i++) { row[i] = getters[i].GetValue(item) ?? DBNull.Value; } dataTable.Rows.Add(row); } return(dataTable); }