private static bool IsProjectionPath(MemberExpression m) { while (m.Expression is MemberExpression) { m = (MemberExpression)m.Expression; } PropertyDescriptor pd = TypeDescriptor.GetProperties(m.Member.DeclaringType)[m.Member.Name]; IncludeAttribute includeAtt = (IncludeAttribute)pd.Attributes[typeof(IncludeAttribute)]; return(includeAtt != null && includeAtt.IsProjection); }
/// <summary> /// Called to attempt to resolve unresolved member references during query deserialization. /// </summary> /// <param name="type">The Type the member is expected on.</param> /// <param name="member">The member name.</param> /// <param name="instance">The instance to form the MemberExpression on.</param> /// <returns>A MemberExpression if the member can be resolved, null otherwise.</returns> public override MemberExpression ResolveMember(Type type, string member, Expression instance) { MemberExpression mex = null; IDictionary <PropertyDescriptor, IncludeAttribute[]> entityIncludeMap = MetaType.GetMetaType(type).ProjectionMemberMap; if (entityIncludeMap.Any()) { // Do a reverse lookup in the include map for the type, looking // for the source of the member (if present) PropertyDescriptor pd = null; IncludeAttribute projection = null; foreach (var entry in entityIncludeMap) { projection = entry.Value.SingleOrDefault(p => p.IsProjection && p.MemberName == member); if (projection != null) { pd = entry.Key; break; } } if (projection == null) { return(null); } // Found the source projection. Form the corresponding MemberExpression // for the projection path string[] pathMembers = projection.Path.Split('.'); Type currType = type; MemberInfo memberInfo = currType.GetMember(pd.Name).Single(); mex = Expression.MakeMemberAccess(instance, memberInfo); foreach (string pathMember in pathMembers) { currType = mex.Type; memberInfo = currType.GetMember(pathMember).Single(); mex = Expression.MakeMemberAccess(mex, memberInfo); } } return(mex); }
public void ConstructorTest() { var includeAttribute = new IncludeAttribute(); Assert.IsNotNull(includeAttribute); }
protected virtual IEnumerable <Attribute> GetEntityMemberAttributes(PropertyDescriptor propertyDescriptor) { if (_classMetadata == null) { return(null); } var attributes = new List <Attribute>(); //KeyAttributes if (_classMetadata.Identifier != null) { foreach (Column id in _identifierCols) { if (id.Name == propertyDescriptor.Name) { if (propertyDescriptor.Attributes[typeof(KeyAttribute)] == null) { attributes.Add(new KeyAttribute()); } if (propertyDescriptor.Attributes[typeof(EditableAttribute)] == null) { //An identifier is not editable, sometimes anyway it allow an initial value var editable = new EditableAttribute(false); if (id.Value is SimpleValue) { editable.AllowInitialValue = "assigned".Equals(((SimpleValue)id.Value).IdentifierGeneratorStrategy, StringComparison.InvariantCultureIgnoreCase); } attributes.Add(editable); } break; } } } Property member = _classMetadata.PropertyIterator.FirstOrDefault(x => x.Name == propertyDescriptor.Name); if (member == null) //If ther's no mapping in nhibernate... { return(attributes); } //Required if ((!member.IsNullable) && (propertyDescriptor.PropertyType.IsValueType && (propertyDescriptor.Attributes[typeof(RequiredAttribute)] == null))) { attributes.Add(new RequiredAttribute()); } //Association if (member.Type.IsAssociationType && (propertyDescriptor.Attributes[typeof(AssociationAttribute)] == null)) { string name; string thisKey = ""; string otherkey = ""; if (member.Type.IsCollectionType) { name = propertyDescriptor.ComponentType.FullName + "_" + member.Name; if (member.Type.ReturnedClass.GetGenericArguments().Length != 1) { throw new Exception( String.Format( "The property {0} is not a generic collection as expected (like IList<T>)...", member.Name)); } Type targetClassType = member.Type.ReturnedClass.GetGenericArguments()[0]; foreach (Column col in _identifierCols) { thisKey += (thisKey != "" ? ", " : "") + col.Name; //*****Naming convention**** //Here I'm assuming that the name of each field in the type that holds the foreign key observe //the following structure: string field = member.Name.Replace(Inflector.Pluralize(targetClassType.Name), "") + propertyDescriptor.ComponentType.Name + "_" + col.Name; otherkey += (otherkey != "" ? ", " : "") + field; if (targetClassType.GetProperties(BindingFlags.Public | BindingFlags.Instance).SingleOrDefault(x => x.Name == field) == null) { throw new Exception(String.Format("The class {0} doesn't contain a Property named {1}", targetClassType.Name, field)); } } } else //Member is a class type { //Key could be composite, cycle every identifier on "the other side" PersistentClass otherMappingClass = _nhibernateConfiguration.GetClassMapping(member.Type.ReturnedClass); foreach (Column col in otherMappingClass.Key.ColumnIterator) { //Naming Convention: //The name of each foreign key field be MUST BE the name of the class field + "_" + the name of the key field in the targetclass thisKey += (thisKey != "" ? ", " : "") + member.Name + "_" + col.Name; otherkey += (otherkey != "" ? ", " : "") + col.Name; } //Check: this name MUST ALWAYS BE the same on the both side of a bi-directional association name = member.Type.ReturnedClass.FullName + "_" + Inflector.Pluralize(member.PersistentClass.NodeName); } //CHECK: When do you want to add an IncludeAttribute ? if (!_classMetadata.IsLazy) { var incAttr = new IncludeAttribute(); attributes.Add(incAttr); } var attribute = new AssociationAttribute( name, thisKey, otherkey ); Type fromParent = ForeignKeyDirection.ForeignKeyFromParent.GetType(); attribute.IsForeignKey = fromParent.IsInstanceOfType(((IAssociationType)member.Type).ForeignKeyDirection); attributes.Add(attribute); } //RoundtripOriginal if (member == _classMetadata.Version) { attributes.Add(new RoundtripOriginalAttribute()); } return(attributes.ToArray()); }