public static IQueryable <TEntity> EagerFetchAll <TEntity>(this IQueryable <TEntity> query) { // hack the session reference out of the provider - or is // there a better way to do this? //IStatelessSession session = (IStatelessSession)query.Provider.GetType().GetProperty("Session").GetValue(query.Provider); //ISession session = (ISession)query.Provider.GetType() // .GetProperty("Session", System.Reflection.BindingFlags.Instance // | System.Reflection.BindingFlags.NonPublic) // .GetValue(query.Provider); var entityType = typeof(TEntity); var sessionFactory = Ioc.Create <ISessionFactory>(); IClassMetadata metaData = sessionFactory.GetClassMetadata(entityType); for (int i = 0; i < metaData.PropertyNames.Length; i++) { global::NHibernate.Type.IType propType = metaData.PropertyTypes[i]; // get eagerly mapped associations to other entities if (propType.IsAssociationType && !metaData.PropertyLaziness[i]) { ParameterExpression par = Expression.Parameter(entityType, "p"); Expression propExp = Expression.Property(par, metaData.PropertyNames[i]); Type relatedType = null; LambdaExpression lambdaExp; string methodName; if (propType.ReturnedClass.IsGenericCollection()) { relatedType = propType.ReturnedClass.GetGenericArguments()[0]; var funcType = typeof(Func <,>).MakeGenericType(entityType, typeof(IEnumerable <>).MakeGenericType(relatedType)); lambdaExp = Expression.Lambda(funcType, propExp, par); methodName = "FetchMany"; } else { relatedType = propType.ReturnedClass; lambdaExp = Expression.Lambda(propExp, par); methodName = "Fetch"; } var fetchManyMethodImpl = typeof(EagerFetchingExtensionMethods).GetMethod(methodName).MakeGenericMethod(entityType, relatedType); Expression callExpr = Expression.Call(null, fetchManyMethodImpl, // first parameter is the query, second is property access expression query.Expression, lambdaExp ); LambdaExpression expr = Expression.Lambda(callExpr, par); Type fetchGenericType = typeof(NhFetchRequest <,>).MakeGenericType(entityType, propType.ReturnedClass); query = (IQueryable <TEntity>)Activator.CreateInstance(fetchGenericType, query.Provider, callExpr); } } return(query); }
/// <summary> /// Add, update, or delete the entity according to its EntityState. /// </summary> /// <param name="entityInfo"></param> private void ProcessEntity(EntityInfo entityInfo, IClassMetadata classMeta) { var entity = entityInfo.Entity; var state = entityInfo.EntityState; // Restore the old value of the concurrency column so Hibernate will be able to save the entity if (classMeta.IsVersioned) { RestoreOldVersionValue(entityInfo, classMeta); } if (state == EntityState.Modified) { session.Update(entity); } else if (state == EntityState.Added) { session.Save(entity); } else if (state == EntityState.Deleted) { session.Delete(entity); } else { // Just re-associate the entity with the session. Needed for many to many to get both ends into the session. session.Lock(entity, LockMode.None); } }
/// <summary> /// Connect the related entities based on the foreign key values. /// Note that this may cause related entities to be loaded from the DB if they are not already in the session. /// </summary> /// <param name="entityInfo">Entity that will be saved</param> /// <param name="meta">Metadata about the entity type</param> private void FixupRelationships(EntityInfo entityInfo, IClassMetadata meta) { var propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; if (meta.IdentifierType != null) { var propType = meta.IdentifierType; if (propType.IsAssociationType && propType.IsEntityType) { FixupRelationship(meta.IdentifierPropertyName, (EntityType)propType, entityInfo, meta); } else if (propType.IsComponentType) { FixupComponentRelationships(meta.IdentifierPropertyName, (ComponentType)propType, entityInfo, meta); } } for (int i = 0; i < propNames.Length; i++) { var propType = propTypes[i]; if (propType.IsAssociationType && propType.IsEntityType) { FixupRelationship(propNames[i], (EntityType)propTypes[i], entityInfo, meta); } else if (propType.IsComponentType) { FixupComponentRelationships(propNames[i], (ComponentType)propType, entityInfo, meta); } } }
/// <summary> /// Removes the reference from collection. /// </summary> /// <param name="targetResource">The target resource.</param> /// <param name="propertyName">Name of the property.</param> /// <param name="resourceToBeRemoved">The resource to be removed.</param> void IUpdatable.RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved) { IClassMetadata metadata = session.SessionFactory.GetClassMetadata(targetResource.GetType().FullName); if (metadata == null) { throw new DataServiceException("Type not recognized as a valid type for this Context"); } // Get the property to use to remove the resource to object collection = metadata.GetPropertyValue(targetResource, propertyName, EntityMode.Poco); // Try with IList implementation first (its faster) if (collection is IList) { ((IList)collection).Remove(resourceToBeRemoved); } else // Try with Reflection's Add() { MethodInfo removeMethod = collection.GetType().GetMethod("Remove", BindingFlags.Public | BindingFlags.Instance); if (removeMethod == null) { throw new DataServiceException(string.Concat("Could not determine the collection type of the ", propertyName, " property.")); } removeMethod.Invoke(collection, new object[] { resourceToBeRemoved }); } }
/// <summary> /// For a given property type, containing type, and property name, return true if it should /// be serialized and false if not. By default, value types and system types are serialized, /// but collections and custom types are not. /// </summary> /// <param name="meta"></param> /// <param name="propertyType"></param> /// <param name="containingType"></param> /// <param name="name"></param> /// <returns></returns> protected bool IsIncluded(IClassMetadata meta, Type propertyType, Type containingType, string name) { if (includedMembers != null && includedMembers.Contains(name)) { return(true); } if (includedTypeMembers != null && includedTypeMembers.ContainsKey(containingType)) { var list = includedTypeMembers[containingType]; if (list.Contains(name)) { return(true); } } if (meta != null && meta.GetPropertyType(name).IsAssociationType) { return(false); } if (typeof(System.Collections.IEnumerable).IsAssignableFrom(propertyType)) { return(false); } return(true); }
/// <summary> /// Get the value of the foreign key property. This comes from the entity, but if that value is /// null, and the entity is deleted, we try to get it from the originalValuesMap. /// </summary> /// <param name="entityInfo">Breeze EntityInfo</param> /// <param name="meta">Metadata for the entity class</param> /// <param name="foreignKeyName">Name of the foreign key property of the entity, e.g. "CustomerID"</param> /// <returns></returns> private object GetForeignKeyValue(EntityInfo entityInfo, IClassMetadata meta, string foreignKeyName) { var entity = entityInfo.Entity; object id = null; if (foreignKeyName == meta.IdentifierPropertyName) { id = meta.GetIdentifier(entity, EntityMode.Poco); } else if (meta.PropertyNames.Contains(foreignKeyName)) { id = meta.GetPropertyValue(entity, foreignKeyName, EntityMode.Poco); } else if (meta.IdentifierType.IsComponentType) { // compound key var compType = meta.IdentifierType as ComponentType; var index = Array.IndexOf <string>(compType.PropertyNames, foreignKeyName); if (index >= 0) { var idComp = meta.GetIdentifier(entity, EntityMode.Poco); id = compType.GetPropertyValue(idComp, index, EntityMode.Poco); } } if (id == null && entityInfo.EntityState == EntityState.Deleted) { entityInfo.OriginalValuesMap.TryGetValue(foreignKeyName, out id); } return(id); }
/// <summary> /// Add, update, or delete the entity according to its EntityState. /// </summary> /// <param name="entityInfo"></param> protected async Task ProcessEntityAsync(EntityInfo entityInfo, IClassMetadata classMeta) { var entity = entityInfo.Entity; var state = entityInfo.EntityState; // Restore the old value of the concurrency column so Hibernate will be able to save the entity if (classMeta.IsVersioned) { RestoreOldVersionValue(entityInfo, classMeta); } if (state == EntityState.Modified) { CheckForKeyUpdate(entityInfo, classMeta); await Session.UpdateAsync(entity); } else if (state == EntityState.Added) { await Session.SaveAsync(entity); } else if (state == EntityState.Deleted) { await Session.DeleteAsync(entity); } }
/// <summary> /// Get the identifier value for the entity. If the entity does not have an /// identifier property, or natural identifiers defined, then the entity itself is returned. /// </summary> /// <param name="entity"></param> /// <param name="meta"></param> /// <returns></returns> protected object GetIdentifier(object entity, IClassMetadata meta = null) { var type = Session.GetProxyRealType(entity); meta = meta ?? Session.SessionFactory.GetClassMetadata(type); if (meta.IdentifierType != null) { var id = meta.GetIdentifier(entity); if (meta.IdentifierType.IsComponentType) { var compType = (ComponentType)meta.IdentifierType; return(compType.GetPropertyValues(id)); } return(id); } if (meta.HasNaturalIdentifier) { var idprops = meta.NaturalIdentifierProperties; var values = meta.GetPropertyValues(entity); var idvalues = idprops.Select(i => values[i]).ToArray(); return(idvalues); } return(entity); }
/// <summary> /// Add, update, or delete the entity according to its EntityState. /// </summary> /// <param name="entityInfo"></param> protected void ProcessEntity(EntityInfo entityInfo, IClassMetadata classMeta) { var entity = entityInfo.Entity; var state = entityInfo.EntityState; // Restore the old value of the concurrency column so Hibernate will be able to save the entity if (classMeta.IsVersioned) { RestoreOldVersionValue(entityInfo, classMeta); } if (state == EntityState.Modified) { session.Update(entity); } else if (state == EntityState.Added) { session.Save(entity); } else if (state == EntityState.Deleted) { session.Delete(entity); } else { // Ignore EntityState.Unchanged. Too many problems using session.Lock or session.Merge //session.Lock(entity, LockMode.None); } }
void FilterLeafNode(CompositeNode parent, LeafNode leafnode, IClassMetadata metadata) { if (string.IsNullOrEmpty(leafnode.Value.ToString())) { return; } if (leafnode.IsArray && string.IsNullOrEmpty(((string[])leafnode.Value).Join(""))) { return; } if (leafnode.Value.ToString() == "all") { return; } var fieldname = leafnode.FullName.Replace("root.", ""); if (Fields.Contains(fieldname)) { StraightLeafNode(parent, leafnode, fieldname); } else { RangeLeafNode(leafnode, metadata); } }
private IEnumerable <TreeNode> GetTreeNodes(Table table, Identifier identifier) { List <TreeNode> treeNodes = new List <TreeNode>(); IClassMetadata classMetadata = Schema.GetClassMetadata(table.PersistentClass); if (table.ResultsClass != null) { TreeNode resultsNode = new TreeNode { Name = "Results", Text = ResultText(table, "Results") }; // Not L10N foreach (TreeNode treeNode in GetTreeNodes(Schema.GetClassMetadata(table.ResultsClass), identifier)) { ((NodeData)treeNode.Tag).Results = true; resultsNode.Nodes.Add(treeNode); } treeNodes.Add(resultsNode); } if (table.ResultsSummaryClass != null) { TreeNode resultsSummaryNode = new TreeNode { Name = "ResultsSummary", // Not L10N Text = ResultText(table, "ResultsSummary") // Not L10N }; foreach (TreeNode treeNode in GetTreeNodes(Schema.GetClassMetadata(table.ResultsSummaryClass), identifier)) { ((NodeData)treeNode.Tag).ResultsSummary = true; resultsSummaryNode.Nodes.Add(treeNode); } treeNodes.Add(resultsSummaryNode); } treeNodes.AddRange(GetTreeNodes(classMetadata, identifier)); return(treeNodes); }
/// <summary> /// Replaces the resource. /// </summary> /// <param name="resource">The resource to reset.</param> /// <returns></returns> object IUpdatable.ResetResource(object resource) { IUpdatable update = this; // Create a new resource of the same type // but only make a local copy as we're only using it to set the default fields // Get the metadata IClassMetadata metadata = session.SessionFactory.GetClassMetadata(resource.GetType().ToString()); object tempCopy = metadata.Instantiate(null, EntityMode.Poco); for (int i = 0; i < metadata.PropertyNames.Length; i++) { var propertyType = metadata.PropertyTypes[i]; var propName = metadata.PropertyNames[i]; if (!propertyType.IsEntityType) { object value = metadata.GetPropertyValue(tempCopy, propName, EntityMode.Poco); update.SetValue(resource, propName, value); } } //Return the new resource return(resource); }
public override TypedValue[] GetTypedValues(ISessionFactoryImplementor sessionFactory, System.Type persistentClass, IDictionary aliasClasses) { IClassMetadata meta = sessionFactory.GetClassMetadata(persistentClass); string[] propertyNames = meta.PropertyNames; IType[] propertyTypes = meta.PropertyTypes; object[] values = meta.GetPropertyValues(_entity); ArrayList list = new ArrayList(); for (int i = 0; i < propertyNames.Length; i++) { object value = values[i]; IType type = propertyTypes[i]; string name = propertyNames[i]; bool isPropertyIncluded = (i != meta.VersionProperty && IsPropertyIncluded(value, name, type)); if (isPropertyIncluded) { if (propertyTypes[i].IsComponentType) { AddComponentTypedValues(name, value, (IAbstractComponentType)type, list); } else { AddPropertyTypedValue(value, type, list); } } } return((TypedValue[])list.ToArray(typeof(TypedValue))); }
/// <summary> /// Wrapper class to produce an Ado.Net Datatable from any entity, /// and perform SqlBulkCopy operations /// </summary> public SqlEntityBulkCopy(string sqlCnnString, Type entityType) { if (Cfg == null) { //Note: The NHibernate.Cfg.Configuration is meant only as an initialization-time object. //Note: NHibernate.ISessionFactory is immutable and does not retain any association back to the Session Cfg = new Configuration(); //Cfg.SetProperty("proxyfactory.factory_class", "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"); Cfg.SetProperty("dialect", "NHibernate.Dialect.MsSql2008Dialect"); Cfg.SetProperty("connection.provider", "NHibernate.Connection.DriverConnectionProvider"); Cfg.SetProperty("connection.driver_class", "NHibernate.Driver.SqlClientDriver"); Cfg.SetProperty("connection.connection_string", sqlCnnString); //add all the mappings embedded in this assembly Cfg.AddAssembly(typeof(SqlEntityBulkCopy).Assembly); var sessionFactory = Cfg.BuildSessionFactory(); SessionFactoryImpl = (ISessionFactoryImplementor)sessionFactory; } EntityType = entityType; //_session = SessionFactoryImpl.OpenSession(); _metaData = SessionFactoryImpl.GetClassMetadata(EntityType); _persistentClass = Cfg.GetClassMapping(EntityType); _sqlCnn = new SqlConnection(sqlCnnString); _sqlBulkCopy = new SqlBulkCopy(_sqlCnn); //Debug.WriteLine("EntityName = " + _metaData.EntityName); //Debug.WriteLine("IdentifierPropertyName = " + _metaData.IdentifierPropertyName); //Debug.WriteLine("IdentifierType = " + _metaData.IdentifierType); BuildDataTable(); BuildAndMapSqlBulkCopy(); }
private string GetSelectSql(int?count, string additionalSql) { IClassMetadata metadata = this.Session.SessionFactory.GetClassMetadata(typeof(ModelType)); SingleTableEntityPersister entityPersister = metadata as SingleTableEntityPersister; string[] subclassColumnClosure = entityPersister.GetType().GetProperty("SubclassColumnClosure", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(entityPersister, null) as string[]; List <string> selectColumns = new List <string>(); string idColumn = entityPersister.IdentifierPropertyName; selectColumns.Add(idColumn); for (int i = 0; i < entityPersister.PropertyNames.Length; i++) { string propertyName = entityPersister.PropertyNames[i]; string columnName = subclassColumnClosure[i]; string selectColumn = columnName; if (propertyName != columnName) { selectColumn = string.Format("{0} as {1}", columnName, propertyName); } selectColumns.Add(selectColumn); } string top = ""; if (count.HasValue) { top = "top " + count; } string sql = string.Format("SELECT {0} {1} from {2} {3}", top, string.Join(",", selectColumns), entityPersister.TableName, additionalSql); return(sql); }
/// <summary> /// /// </summary> /// <param name="entity">an actual entity object, not a proxy!</param> /// <param name="entityMode"></param> /// <returns></returns> public string ToString(object entity, EntityMode entityMode) { IClassMetadata cm = _factory.GetClassMetadata(entity.GetType()); if (cm == null) { return(entity.GetType().FullName); } IDictionary <string, string> result = new Dictionary <string, string>(); if (cm.HasIdentifierProperty) { result[cm.IdentifierPropertyName] = cm.IdentifierType.ToLoggableString(cm.GetIdentifier(entity, entityMode), _factory); } IType[] types = cm.PropertyTypes; string[] names = cm.PropertyNames; object[] values = cm.GetPropertyValues(entity, entityMode); for (int i = 0; i < types.Length; i++) { result[names[i]] = types[i].ToLoggableString(values[i], _factory); } return(cm.EntityName + CollectionPrinter.ToString(result)); }
public static Core.Validator GetValidatorFromSession(ISessionFactory sessionFactory) { var allDefindedClasses = sessionFactory.GetAllClassMetadata(); Core.Validator validator = new Core.Validator(); foreach (KeyValuePair <string, IClassMetadata> pair in allDefindedClasses) { IClassMetadata metadata = pair.Value; foreach (string propertyName in metadata.PropertyNames) { IType propertyType = metadata.GetPropertyType(propertyName); StringType st = propertyType as StringType; if (st != null) { if (st.SqlType.Length > 0) { validator.AddRule(Rule.For(metadata.GetMappedClass(EntityMode.Poco)) .OnMember(propertyName) .MaxLength(st.SqlType.Length) .Message(String.Format( "Property {0} have a maximum length of {1}", propertyName, st.SqlType.Length))); } } } } return(validator); }
public object GetResourceByStringId(Type resource, string resId) { if (resource == typeof(string)) { return(resId); } IClassMetadata perisisteType = SessionManager.GetSessionWrapper() .SessionFactory.GetClassMetadata(resource); if (perisisteType == null) { throw new MemberShipException("Resource type " + resource.GetType().Name + " is not belong to nhibernate mapping class"); } var identity = perisisteType.IdentifierType as PrimitiveType; object id; if (identity != null) { id = identity.FromStringValue(resId); } else { var emub = perisisteType.IdentifierType as ImmutableType; id = emub.FromStringValue(resId); } return(CurrentSession.Get(resource, id)); }
/// <summary> /// Add the metadata for an entity. /// </summary> /// <param name="meta"></param> void AddClass(IClassMetadata meta) { var type = meta.GetMappedClass(EntityMode.Poco); // "Customer:#Breeze.Nhibernate.NorthwindIBModel": { var classKey = type.Name + ":#" + type.Namespace; var cmap = new Dictionary<string, object>(); _typeList.Add(cmap); cmap.Add("shortName", type.Name); cmap.Add("namespace", type.Namespace); var entityPersister = meta as IEntityPersister; var generator = entityPersister != null ? entityPersister.IdentifierGenerator : null; if (generator != null) { string genType = null; if (generator is IdentityGenerator) genType = "Identity"; else if (generator is Assigned) genType = "None"; else genType = "KeyGenerator"; cmap.Add("autoGeneratedKeyType", genType); // TODO find the real generator } var resourceName = Pluralize(type.Name); // TODO find the real name cmap.Add("defaultResourceName", resourceName); _resourceMap.Add(resourceName, classKey); var dataList = new List<Dictionary<string, object>>(); cmap.Add("dataProperties", dataList); var navList = new List<Dictionary<string, object>>(); cmap.Add("navigationProperties", navList); var persistentClass = _configuration.GetClassMapping(type); AddClassProperties(meta, persistentClass, dataList, navList); }
void FilterPrimaryKey(LeafNode leafnode, IClassMetadata metadata, DetachedCriteria query) { if (string.IsNullOrEmpty(leafnode.Value.ToString())) { return; } if (leafnode.Value.Equals("all")) { return; } var valuesplit = HttpUtility.UrlDecode(leafnode.Value.ToString()).Split(','); var pktype = metadata.IdentifierType.ReturnedClass; if (valuesplit.Length > 1) { try { var ar = valuesplit .Select(p => { var success = false; var id = Converter.Convert(pktype, typeof(string), p, out success); return(success ? id : null); }) .Where(p => p != null) .Select(p => Restrictions.Eq(Projections.Id(), p)).ToArray(); if (ar.Length > 0) { var disjunction = Restrictions.Disjunction(); foreach (var o in ar) { disjunction.Add(o); } query.Add(disjunction); SetParam(leafnode); } } catch (Exception e) { Logger.ErrorFormat(e, "Could not convert value '{0}' to type '{2}'", leafnode.Value, metadata.IdentifierType.ReturnedClass); } } else { if (leafnode.Value.Equals("null")) { query.Add(Restrictions.IsNull(Projections.Id())); SetParam(leafnode); } else { var success = false; Converter.CanConvert(pktype, typeof(string), leafnode.Value.ToString(), out success); if (success) { var id = Converter.Convert(pktype, typeof(string), leafnode.Value.ToString(), out success); query.Add(Restrictions.Eq(Projections.Id(), id)); SetParam(leafnode); } } } }
public ExpressionInfo(Expression expression, IClassMetadata metadata) { _originalQuery = expression; Expression = expression; Metadata = metadata; TotalColumns = GetTotalColumns(metadata); }
public string AddIncludedProperty(string propertyName, IClassMetadata propertyTypeMetadata, IQueryableCollection collectionMetadata, bool root) { if (root) { _currentPath = propertyName; } else if (!string.IsNullOrEmpty(_currentPath)) { _currentPath = $"{_currentPath}.{propertyName}"; } if (_includedPaths.ContainsKey(_currentPath)) { return(null); } var columns = propertyTypeMetadata == null ? GetTotalColumns(collectionMetadata) : GetTotalColumns(propertyTypeMetadata); _includedPaths.Add(_currentPath, columns); TotalColumns += columns; return(_currentPath); }
/// <summary> /// Get the identifier value for the entity. If the entity does not have an /// identifier property, or natural identifiers defined, then the entity itself is returned. /// </summary> /// <param name="entity"></param> /// <param name="meta"></param> /// <returns></returns> private object GetIdentifier(object entity, IClassMetadata meta = null) { var type = entity.GetType(); meta = meta ?? session.SessionFactory.GetClassMetadata(type); if (meta.IdentifierType != null) { var id = meta.GetIdentifier(entity, EntityMode.Poco); if (meta.IdentifierType.IsComponentType) { var compType = (ComponentType)meta.IdentifierType; return(compType.GetPropertyValues(id, EntityMode.Poco)); } else { return(id); } } else if (meta.HasNaturalIdentifier) { var idprops = meta.NaturalIdentifierProperties; var values = meta.GetPropertyValues(entity, EntityMode.Poco); var idvalues = idprops.Select(i => values[i]).ToArray(); return(idvalues); } return(entity); }
/// <summary> /// Return names of all properties that are defined in the mapped ancestors of the /// given persister. Note that unmapped superclasses are deliberately ignored, because /// they shouldn't affect the metadata. /// </summary> /// <param name="persister"></param> /// <returns>set of property names. Empty if the persister doesn't have a superclass.</returns> HashSet <string> GetSuperProperties(AbstractEntityPersister persister) { HashSet <string> set = new HashSet <String>(); if (!persister.IsInherited) { return(set); } string superClassName = persister.MappedSuperclass; if (superClassName == null) { return(set); } IClassMetadata superMeta = _sessionFactory.GetClassMetadata(superClassName); if (superMeta == null) { return(set); } string[] superProps = superMeta.PropertyNames; set = new HashSet <string>(superProps); set.Add(superMeta.IdentifierPropertyName); return(set); }
public override SqlString ToSqlString( ISessionFactoryImplementor factory, System.Type persistentClass, string alias, IDictionary aliasClasses) { SqlStringBuilder builder = new SqlStringBuilder(); builder.Add(StringHelper.OpenParen); IClassMetadata meta = factory.GetClassMetadata(persistentClass); String[] propertyNames = meta.PropertyNames; IType[] propertyTypes = meta.PropertyTypes; object[] propertyValues = meta.GetPropertyValues(_entity); for (int i = 0; i < propertyNames.Length; i++) { object propertyValue = propertyValues[i]; String propertyName = propertyNames[i]; bool isPropertyIncluded = i != meta.VersionProperty && IsPropertyIncluded(propertyValue, propertyName, propertyTypes[i]); if (isPropertyIncluded) { if (propertyTypes[i].IsComponentType) { AppendComponentCondition( propertyName, propertyValue, (IAbstractComponentType)propertyTypes[i], persistentClass, alias, aliasClasses, factory, builder ); } else { AppendPropertyCondition( propertyName, propertyValue, persistentClass, alias, aliasClasses, factory, builder ); } } } if (builder.Count == 1) { builder.Add("1=1"); // yuck! } builder.Add(StringHelper.ClosedParen); return(builder.ToSqlString()); }
/// <summary> /// Initializes a new instance of the <see cref="ManagerCacheBaseT{TClass,TKey}"/> class. /// </summary> /// <param name="repository"> /// The repository. /// </param> public ManagerCacheBaseT(IManagerBase <TClass, TKey> repository) { Repository = repository; SessionFactory = ObjectFactory.GetInstance <ISessionFactory>(); TimeSpan = new TimeSpan(0, 0, 30, 0); classMetadata = SessionFactory.GetClassMetadata(typeof(TClass)); TimeQueryDb = new DateTime(1900, 1, 1); }
public EntityExpression(string associationPath, string alias, System.Type type, IClassMetadata metaData, Expression expression) : base(IsRoot(expression) ? NHibernateExpressionType.RootEntity : NHibernateExpressionType.Entity, type) { _associationPath = associationPath; _alias = alias; _metaData = metaData; _expression = expression; }
public static string GetTableName <T>( ) { IClassMetadata md = Connection.Database.Instance.SessionFactory.GetClassMetadata(typeof(T)); AbstractEntityPersister aep = md as AbstractEntityPersister; return(aep.TableName); //return new NHibernate.Cfg.Configuration().GetClassMapping(typeof(T)).RootTable.Name; }
/// <summary> /// Add the metadata for an entity. /// </summary> /// <param name="meta"></param> void AddClass(IClassMetadata meta) { var type = meta.GetMappedClass(EntityMode.Poco); // "Customer:#Breeze.Nhibernate.NorthwindIBModel": { var classKey = type.Name + ":#" + type.Namespace; var cmap = new Dictionary <string, object>(); _typeList.Add(cmap); cmap.Add("shortName", type.Name); cmap.Add("namespace", type.Namespace); var persistentClass = _configuration.GetClassMapping(type); var superClass = persistentClass.Superclass; if (superClass != null) { var superType = superClass.MappedClass; var baseTypeName = superType.Name + ":#" + superType.Namespace; cmap.Add("baseTypeName", baseTypeName); } var entityPersister = meta as IEntityPersister; var generator = entityPersister != null ? entityPersister.IdentifierGenerator : null; if (generator != null) { string genType = null; if (generator is IdentityGenerator) { genType = "Identity"; } else if (generator is Assigned || generator is ForeignGenerator) { genType = "None"; } else { genType = "KeyGenerator"; } cmap.Add("autoGeneratedKeyType", genType); // TODO find the real generator } var resourceName = Pluralize(type.Name); // TODO find the real name cmap.Add("defaultResourceName", resourceName); _resourceMap.Add(resourceName, classKey); var dataList = new List <Dictionary <string, object> >(); cmap.Add("dataProperties", dataList); var navList = new List <Dictionary <string, object> >(); cmap.Add("navigationProperties", navList); AddClassProperties(meta, persistentClass, dataList, navList); }
public static IClassMetadata that_returns_property_names( this IClassMetadata dependency, string[] propertyNames) { dependency.Stub(x => x.PropertyNames) .Return(propertyNames); return(dependency); }
static ExplorerIcon GetIcon(IClassMetadata classMetadata, string propertyName) { var propertyType = classMetadata.GetPropertyType(propertyName); return propertyType.IsCollectionType ? ExplorerIcon.OneToMany : propertyType.IsAssociationType ? ExplorerIcon.ManyToOne : ExplorerIcon.Column; }
private static ExplorerItem GetPropertyItem(IClassMetadata classMetadata, string propertyName) { return new ExplorerItem(string.Format("{0}", propertyName), GetKind(classMetadata, propertyName), GetIcon(classMetadata, propertyName)) { Tag = classMetadata.GetPropertyType(propertyName) }; }
public EntityExpression(string associationPath, string alias, System.Type type, IClassMetadata metaData, Expression expression, IDictionary<string, IList<string>> addedAlias) : base(IsRoot(expression) ? NHibernateExpressionType.RootEntity : NHibernateExpressionType.Entity, type) { _associationPath = associationPath; _alias = GetUniqueAlias(associationPath, alias, addedAlias); _metaData = metaData; _expression = expression; }
private static IEnumerable<ExplorerItem> GetId(IClassMetadata classMetadata) { var propertyName = classMetadata.IdentifierPropertyName; if (propertyName != null) yield return new ExplorerItem(propertyName, ExplorerItemKind.Property, ExplorerIcon.Key) { Tag = classMetadata.GetPropertyType(propertyName) }; }
static ExplorerItemKind GetKind(IClassMetadata classMetadata, string propertyName) { var propertyType = classMetadata.GetPropertyType(propertyName); return propertyType.IsCollectionType ? ExplorerItemKind.CollectionLink : propertyType.IsAssociationType ? ExplorerItemKind.ReferenceLink : ExplorerItemKind.Property; }
public static IClassMetadata that_returns_property_names( this IClassMetadata dependency, string[] propertyNames) { A.CallTo(() => dependency.PropertyNames) .Returns(propertyNames); return(dependency); }
/// <summary> /// Initializes the session that will be used to enumerate /// </summary> private void InitSession() { _session = _sessionFactory.OpenSession(); _session.FlushMode = FlushMode.Never; _tx = _session.BeginTransaction(); try { //Handle the case of entity type (InitialLoad) if (_entityType != null) { _criteria = _session.CreateCriteria(_entityType); _criteria.SetCacheable(false); //If perform by id, add order to the criteria if (_performOrderById) { IClassMetadata metadata = _sessionFactory.GetClassMetadata(_entityType); string idPropName = metadata.IdentifierPropertyName; if (idPropName != null) { _criteria.AddOrder(Order.Asc(idPropName)); } } } //Handle the case of Persistency.Query (GetEnumerator) else if (_persistencyQuery != null) { string select = _persistencyQuery.SqlQuery; _query = _session.CreateQuery(select); object[] preparedValues = _persistencyQuery.Parameters; if (preparedValues != null) { for (int i = 0; i < preparedValues.Length; i++) { _query.SetParameter(i, preparedValues[i]); } } _query.SetCacheable(false); _query.SetFlushMode(FlushMode.Never); } else { throw new Exception("NHibernateDataEnumerator must receive an Entity Type or a Query"); } } catch (Exception ex) { if (_tx != null && _tx.IsActive) { _tx.Rollback(); } if (_session.IsOpen) { _session.Close(); } throw new Exception("Error while constructing an enumerator", ex); } }
public MappedClassMetadata(IClassMetadata classMetadata) { Require.NotNull(classMetadata, "classMetadata"); for (int i = 0; i < classMetadata.PropertyNames.Length; i++) BuildDynamicComponentPropertyList(classMetadata.PropertyNames[i], classMetadata.PropertyTypes[i]); IdentifierPropertyName = classMetadata.IdentifierPropertyName; }
private static ExplorerItem GetPropertyItem(ISessionFactory sessionFactory, IClassMetadata classMetadata, string propertyName) { var kind = GetKind(classMetadata, propertyName); var propertyType = classMetadata.GetPropertyType(propertyName); return new ExplorerItem(kind == ExplorerItemKind.Property ? string.Format("{0} ({1})", propertyName, propertyType.ReturnedClass.Name) : propertyName, kind, GetIcon(sessionFactory, classMetadata, propertyName)) { Tag = classMetadata.GetPropertyType(propertyName) }; }
static ExplorerIcon GetIcon(ISessionFactory sessionFactory, IClassMetadata classMetadata, string propertyName) { var propertyType = classMetadata.GetPropertyType(propertyName); return propertyType.IsCollectionType ? ((ICollectionPersister)sessionFactory.GetCollectionMetadata( string.Format("{0}.{1}", classMetadata.GetMappedClass(EntityMode.Poco), propertyName))) .IsManyToMany ? ExplorerIcon.ManyToMany : ExplorerIcon.OneToMany : propertyType.IsAssociationType ? ExplorerIcon.ManyToOne : ExplorerIcon.Column; }
/// <summary> /// For a given property type, containing type, and property name, return true if it should /// be serialized and false if not. By default, value types and system types are serialized, /// but collections and custom types are not. /// </summary> /// <param name="meta"></param> /// <param name="propertyType"></param> /// <param name="containingType"></param> /// <param name="name"></param> /// <returns></returns> protected bool IsIncluded(IClassMetadata meta, Type propertyType, Type containingType, string name) { if (includedMembers != null && includedMembers.Contains(name)) return true; if (includedTypeMembers != null && includedTypeMembers.ContainsKey(containingType)) { var list = includedTypeMembers[containingType]; if (list.Contains(name)) return true; } if (meta != null && meta.GetPropertyType(name).IsAssociationType) return false; if (typeof(System.Collections.IEnumerable).IsAssignableFrom(propertyType)) return false; return true; }
/// <summary> /// /// </summary> /// <param name="metadata"></param> public PersistentClassInfo(IClassMetadata metadata) { if (metadata == null) throw new MissingMetadataException("The metadata info of persistent class cannot be null."); this.metadata = metadata; this.properties = new HashSet<IPropertyInfo>(); try { string idName = metadata.IdentifierPropertyName; IType type = metadata.GetPropertyType(idName); this.identifier = new PropertyMapInfo(type, idName); } catch (Exception) { //metadata.GetPropertyValuesToInsert() } metadata.PropertyNames.All ( property => { try { IType type = metadata.GetPropertyType(property); PropertyMapInfo current = new PropertyMapInfo(type, property); properties.Add(current); } catch (Exception) { // } return true; } ); }
private object GetArray(Type elemetType, IClassMetadata classMetadata, CultureInfo culture) { Array aryType = Array.CreateInstance(classMetadata.IdentifierType.ReturnedClass, 0); var idArray = (object[])_result.ConvertTo(aryType.GetType(), culture); var result = new ArrayList(); foreach (object id in idArray) { if (!String.IsNullOrEmpty(id.ToString())) { object pesisite = _sessionWrapper.CurrentSession.Get(elemetType, id); result.Add(pesisite); } } Array arrayRsult = Array.CreateInstance(elemetType, result.Count); for (int index = 0; index < result.Count; index++) { object a = result[index]; arrayRsult.SetValue(a, index); } return arrayRsult; }
public ClassMetadataNodeFactory( ISession session, IClassMetadata metadata ) { _session = session; _metadata = metadata; }
/// <summary> /// Return the property value for the given entity. /// </summary> /// <param name="meta"></param> /// <param name="entity"></param> /// <param name="propName">If null, the identifier property will be returned.</param> /// <returns></returns> private object GetPropertyValue(IClassMetadata meta, object entity, string propName) { if (propName == null || propName == meta.IdentifierPropertyName) return meta.GetIdentifier(entity, EntityMode.Poco); else return meta.GetPropertyValue(entity, propName, EntityMode.Poco); }
/// <summary> /// Get the value of the foreign key property. This comes from the entity, but if that value is /// null, and the entity is deleted, we try to get it from the originalValuesMap. /// </summary> /// <param name="entityInfo">Breeze EntityInfo</param> /// <param name="meta">Metadata for the entity class</param> /// <param name="foreignKeyName">Name of the foreign key property of the entity, e.g. "CustomerID"</param> /// <returns></returns> private object GetForeignKeyValue(EntityInfo entityInfo, IClassMetadata meta, string foreignKeyName) { var entity = entityInfo.Entity; object id = null; if (foreignKeyName == meta.IdentifierPropertyName) id = meta.GetIdentifier(entity, EntityMode.Poco); else if (meta.PropertyNames.Contains(foreignKeyName)) id = meta.GetPropertyValue(entity, foreignKeyName, EntityMode.Poco); else if (meta.IdentifierType.IsComponentType) { // compound key var compType = meta.IdentifierType as ComponentType; var index = Array.IndexOf<string>(compType.PropertyNames, foreignKeyName); if (index >= 0) { var idComp = meta.GetIdentifier(entity, EntityMode.Poco); id = compType.GetPropertyValue(idComp, index, EntityMode.Poco); } } if (id == null && entityInfo.EntityState == EntityState.Deleted) { entityInfo.OriginalValuesMap.TryGetValue(foreignKeyName, out id); } return id; }
/// <summary> /// Find a foreign key matching the given property, by looking in the fkMap. /// The property may be defined on the class or a superclass, so this function calls itself recursively. /// </summary> /// <param name="propName">Name of the property e.g. "Product"</param> /// <param name="meta">Class metadata, for traversing the class hierarchy</param> /// <returns>The name of the foreign key, e.g. "ProductID"</returns> private string FindForeignKey(string propName, IClassMetadata meta) { var relKey = meta.EntityName + '.' + propName; if (fkMap.ContainsKey(relKey)) { return fkMap[relKey]; } else if (meta.IsInherited && meta is AbstractEntityPersister) { var superEntityName = ((AbstractEntityPersister)meta).MappedSuperclass; var superMeta = session.SessionFactory.GetClassMetadata(superEntityName); return FindForeignKey(propName, superMeta); } else { throw new ArgumentException("Foreign Key '" + relKey + "' could not be found."); } }
/// <summary> /// Get a related entity based on the value of the foreign key. Attempts to find the related entity in the /// saveMap; if its not found there, it is loaded via the Session (which should create a proxy, not actually load /// the entity from the database). /// Related entities are Promoted in the saveOrder according to their state. /// </summary> /// <param name="propName">Name of the navigation/association property of the entity, e.g. "Customer". May be null if the property is the entity's identifier.</param> /// <param name="propType">Type of the property</param> /// <param name="entityInfo">Breeze EntityInfo</param> /// <param name="meta">Metadata for the entity class</param> /// <returns></returns> private object GetRelatedEntity(string propName, EntityType propType, EntityInfo entityInfo, IClassMetadata meta) { object relatedEntity = null; string foreignKeyName = FindForeignKey(propName, meta); object id = GetForeignKeyValue(entityInfo, meta, foreignKeyName); if (id != null) { EntityInfo relatedEntityInfo = FindInSaveMap(propType.ReturnedClass, id); if (relatedEntityInfo == null) { var state = entityInfo.EntityState; if (state != EntityState.Deleted || !propType.IsNullable) { var relatedEntityName = propType.Name; relatedEntity = session.Load(relatedEntityName, id, LockMode.None); } } else { bool removeReverseRelationship = propType.UseLHSPrimaryKey; AddToGraph(entityInfo, relatedEntityInfo, removeReverseRelationship); relatedEntity = relatedEntityInfo.Entity; } } return relatedEntity; }
/// <summary> /// Add the properties for an entity. /// </summary> /// <param name="meta"></param> /// <param name="pClass"></param> /// <param name="dataList">will be populated with the data properties of the entity</param> /// <param name="navList">will be populated with the navigation properties of the entity</param> void AddClassProperties(IClassMetadata meta, PersistentClass pClass, List<Dictionary<string, object>> dataList, List<Dictionary<string, object>> navList) { // maps column names to their related data properties. Used in MakeAssociationProperty to convert FK column names to entity property names. var relatedDataPropertyMap = new Dictionary<string, Dictionary<string, object>>(); var persister = meta as AbstractEntityPersister; var type = pClass.MappedClass; var propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; var propNull = meta.PropertyNullability; for (int i = 0; i < propNames.Length; i++) { var propName = propNames[i]; var pClassProp = pClass.GetProperty(propName); if (!hasOwnProperty(pClass, pClassProp)) continue; // skip property defined on superclass var propType = propTypes[i]; if (!propType.IsAssociationType) // skip association types until we handle all the data types, so the relatedDataPropertyMap will be populated. { var propColumns = pClassProp.ColumnIterator.ToList(); if (propType.IsComponentType) { // complex type var compType = (ComponentType)propType; var complexTypeName = AddComponent(compType, propColumns); var compMap = new Dictionary<string, object>(); compMap.Add("nameOnServer", propName); compMap.Add("complexTypeName", complexTypeName); compMap.Add("isNullable", propNull[i]); dataList.Add(compMap); } else { // data property var col = propColumns.Count() == 1 ? propColumns[0] as Column : null; var isKey = meta.HasNaturalIdentifier && meta.NaturalIdentifierProperties.Contains(i); var isVersion = meta.IsVersioned && i == meta.VersionProperty; var dmap = MakeDataProperty(propName, propType.Name, propNull[i], col, isKey, isVersion); dataList.Add(dmap); var columnNameString = GetPropertyColumnNames(persister, propName); relatedDataPropertyMap.Add(columnNameString, dmap); } } } // Hibernate identifiers are excluded from the list of data properties, so we have to add them separately if (meta.HasIdentifierProperty && hasOwnProperty(pClass, meta.IdentifierPropertyName)) { var dmap = MakeDataProperty(meta.IdentifierPropertyName, meta.IdentifierType.Name, false, null, true, false); dataList.Insert(0, dmap); var columnNameString = GetPropertyColumnNames(persister, meta.IdentifierPropertyName); relatedDataPropertyMap.Add(columnNameString, dmap); } else if (meta.IdentifierType != null && meta.IdentifierType.IsComponentType && pClass.Identifier is Component && ((Component)pClass.Identifier).Owner == pClass) { // composite key is a ComponentType var compType = (ComponentType)meta.IdentifierType; var compNames = compType.PropertyNames; for (int i = 0; i < compNames.Length; i++) { var compName = compNames[i]; var propType = compType.Subtypes[i]; if (!propType.IsAssociationType) { var dmap = MakeDataProperty(compName, propType.Name, compType.PropertyNullability[i], null, true, false); dataList.Insert(0, dmap); } else { var manyToOne = propType as ManyToOneType; //var joinable = manyToOne.GetAssociatedJoinable(this._sessionFactory); var propColumnNames = GetPropertyColumnNames(persister, compName); var assProp = MakeAssociationProperty(type, (IAssociationType)propType, compName, propColumnNames, pClass, relatedDataPropertyMap, true); navList.Add(assProp); } } } // We do the association properties after the data properties, so we can do the foreign key lookups for (int i = 0; i < propNames.Length; i++) { var propName = propNames[i]; if (!hasOwnProperty(pClass, propName)) continue; // skip property defined on superclass var propType = propTypes[i]; if (propType.IsAssociationType) { // navigation property var propColumnNames = GetPropertyColumnNames(persister, propName); var assProp = MakeAssociationProperty(type, (IAssociationType)propType, propName, propColumnNames, pClass, relatedDataPropertyMap, false); navList.Add(assProp); } } }
public FromNHibernateModelBinder(Type modelType, IClassMetadata persistanceInfo) { this.modelType = modelType; this.persistanceInfo = persistanceInfo; ParentPropertyNames = new List<string> { "Parent", modelType.Name}; }
static ICriteria CreateCriteria(ISession session, IClassMetadata classMetadata, string name) { return session.CreateCriteria(classMetadata.EntityName) .SetProjection(Projections.Property(name)); }
/// <summary> /// Set an association value based on the value of the foreign key. This updates the property of the entity. /// </summary> /// <param name="propName">Name of the navigation/association property of the entity, e.g. "Customer". May be null if the property is the entity's identifier.</param> /// <param name="propType">Type of the property</param> /// <param name="entityInfo">Breeze EntityInfo</param> /// <param name="meta">Metadata for the entity class</param> private void FixupRelationship(string propName, EntityType propType, EntityInfo entityInfo, IClassMetadata meta) { var entity = entityInfo.Entity; if (removeMode) { meta.SetPropertyValue(entity, propName, null, EntityMode.Poco); return; } object relatedEntity = GetPropertyValue(meta, entity, propName); if (relatedEntity != null) { // entities are already connected - still need to add to dependency graph EntityInfo relatedEntityInfo = FindInSaveMapByEntity(propType.ReturnedClass, relatedEntity); MaybeAddToGraph(entityInfo, relatedEntityInfo, propType); return; } relatedEntity = GetRelatedEntity(propName, propType, entityInfo, meta); if (relatedEntity != null) meta.SetPropertyValue(entity, propName, relatedEntity, EntityMode.Poco); }
/// <summary> /// Handle a specific property if it is a Association or Component relationship. /// </summary> private void ProcessRelationship(string propName, IType propType, EntityInfo entityInfo, IClassMetadata meta) { if (propType.IsAssociationType && propType.IsEntityType) { FixupRelationship(propName, (EntityType)propType, entityInfo, meta); } else if (propType.IsComponentType) { FixupComponentRelationships(propName, (ComponentType)propType, entityInfo, meta); } }
/// <summary> /// Connect the related entities based on the foreign key values. /// Note that this may cause related entities to be loaded from the DB if they are not already in the session. /// </summary> /// <param name="entityInfo">Entity that will be saved</param> /// <param name="meta">Metadata about the entity type</param> private void ProcessRelationships(EntityInfo entityInfo, IClassMetadata meta) { var propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; if (meta.IdentifierType != null) { ProcessRelationship(meta.IdentifierPropertyName, meta.IdentifierType, entityInfo, meta); } for (int i = 0; i < propNames.Length; i++) { ProcessRelationship(propNames[i], propTypes[i], entityInfo, meta); } }
/// <summary> /// Connect the related entities based on the foreign key values found in a component type. /// This updates the values of the component's properties. /// </summary> /// <param name="propName">Name of the (component) property of the entity. May be null if the property is the entity's identifier.</param> /// <param name="compType">Type of the component</param> /// <param name="entityInfo">Breeze EntityInfo</param> /// <param name="meta">Metadata for the entity class</param> private void FixupComponentRelationships(string propName, ComponentType compType, EntityInfo entityInfo, IClassMetadata meta) { var compPropNames = compType.PropertyNames; var compPropTypes = compType.Subtypes; object component = null; object[] compValues = null; bool isChanged = false; for (int j = 0; j < compPropNames.Length; j++) { var compPropType = compPropTypes[j]; if (compPropType.IsAssociationType && compPropType.IsEntityType) { if (compValues == null) { // get the value of the component's subproperties component = GetPropertyValue(meta, entityInfo.Entity, propName); compValues = compType.GetPropertyValues(component, EntityMode.Poco); } if (compValues[j] == null) { // the related entity is null var relatedEntity = GetRelatedEntity(compPropNames[j], (EntityType)compPropType, entityInfo, meta); if (relatedEntity != null) { compValues[j] = relatedEntity; isChanged = true; } } else if (removeMode) { // remove the relationship compValues[j] = null; isChanged = true; } } } if (isChanged) { compType.SetPropertyValues(component, compValues, EntityMode.Poco); } }
/// <summary> /// Set an association value based on the value of the foreign key. This updates the property of the entity. /// </summary> /// <param name="propName">Name of the navigation/association property of the entity, e.g. "Customer". May be null if the property is the entity's identifier.</param> /// <param name="propType">Type of the property</param> /// <param name="entityInfo">Breeze EntityInfo</param> /// <param name="meta">Metadata for the entity class</param> private void FixupRelationship(string propName, EntityType propType, EntityInfo entityInfo, IClassMetadata meta) { var entity = entityInfo.Entity; if (removeMode) { meta.SetPropertyValue(entity, propName, null, EntityMode.Poco); return; } object relatedEntity = GetPropertyValue(meta, entity, propName); if (relatedEntity != null) return; // entities are already connected relatedEntity = GetRelatedEntity(propName, propType, entityInfo, meta); if (relatedEntity != null) meta.SetPropertyValue(entity, propName, relatedEntity, EntityMode.Poco); }
public TypeMetadata(IClassMetadata metadata, object obj) { string[] prop = metadata.PropertyNames; IType[] types = metadata.PropertyTypes; for (int i = 0; i < prop.Length; i++) { if (!IgnoreAuditHelper.IgnoreAudit(new HibernateType(types[i]), obj, prop[i])) { properties.Add(new HibernateProperty(prop[i], metadata.GetPropertyValue(obj, prop[i]), types[i], obj)); } } }
/// <summary> /// Add the properties for an entity. /// </summary> /// <param name="meta"></param> /// <param name="pClass"></param> /// <param name="dataList">will be populated with the data properties of the entity</param> /// <param name="navList">will be populated with the navigation properties of the entity</param> void AddClassProperties(IClassMetadata meta, PersistentClass pClass, List<Dictionary<string, object>> dataList, List<Dictionary<string, object>> navList) { // Hibernate identifiers are excluded from the list of data properties, so we have to add them separately if (meta.HasIdentifierProperty) { var dmap = MakeDataProperty(meta.IdentifierPropertyName, meta.IdentifierType.Name, false, null, true, false); dataList.Add(dmap); } else if (meta.IdentifierType != null && meta.IdentifierType.IsComponentType) { // composite key is a ComponentType var compType = (ComponentType) meta.IdentifierType; var compNames = compType.PropertyNames; for (int i = 0; i < compNames.Length; i++) { var dmap = MakeDataProperty(compNames[i], compType.Subtypes[i].Name, compType.PropertyNullability[i], null, true, false); dataList.Add(dmap); } } var propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; var propNull = meta.PropertyNullability; for (int i = 0; i < propNames.Length; i++) { var propType = propTypes[i]; var propName = propNames[i]; var propColumns = pClass.GetProperty(propName).ColumnIterator.ToList(); if (propType.IsAssociationType) { // navigation property var atype = (IAssociationType)propType; var nmap = new Dictionary<string, object>(); navList.Add(nmap); nmap.Add("nameOnServer", propName); var entityType = GetEntityType(propType.ReturnedClass, propType.IsCollectionType); nmap.Add("entityTypeName", entityType.Name + ":#" + entityType.Namespace); nmap.Add("isScalar", !propType.IsCollectionType); // the associationName must be the same at both ends of the association. nmap.Add("associationName", GetAssociationName(pClass.MappedClass.Name, entityType.Name, (atype is OneToOneType))); // The foreign key columns usually applies for many-to-one associations IList<string> fks = null; if (propColumns.Any()) { fks = propColumns.Select(c => c.Text).ToList(); nmap.Add("foreignKeyNamesOnServer", fks); } } else if (propType.IsComponentType) { // complex type var compType = (ComponentType)propType; var complexTypeName = AddComponent(compType, propColumns); var compMap = new Dictionary<string, object>(); compMap.Add("nameOnServer", propName); compMap.Add("complexTypeName", complexTypeName); compMap.Add("isNullable", propNull[i]); dataList.Add(compMap); } else { // data property var col = propColumns.Count() == 1 ? propColumns[0] as Column : null; var isKey = meta.HasNaturalIdentifier && meta.NaturalIdentifierProperties.Contains(i); var isVersion = meta.IsVersioned && i == meta.VersionProperty; var dmap = MakeDataProperty(propName, propType.Name, propNull[i], col, isKey, isVersion); dataList.Add(dmap); } // TODO add validators to the property. } }