/// <summary> /// Visits the composite primary key. /// </summary> /// <remarks> /// Validate that the composite key type is implementing GetHashCode() and Equals(), is mark serializable. /// Validate that the compose key is compose of two or more columns /// </remarks> /// <param name="model">The model.</param> public override void VisitCompositePrimaryKey(CompositeKeyModel model) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; Type compositeKeyClassType = model.Property.PropertyType; MethodInfo eq = null; MethodInfo hc = null; new List<MethodInfo>(compositeKeyClassType.GetMethods(flags)).ForEach(delegate(MethodInfo method) { if (method.Name.Equals("Equals")) { ParameterInfo[] parameters = method.GetParameters(); if ((parameters.Length == 1) && (parameters[0].ParameterType == typeof (object))) { eq = method; } } else if (method.Name.Equals("GetHashCode")) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 0) { hc = method; } } }); if (eq == null || hc == null) { throw new ActiveRecordException(String.Format("To use type '{0}' as a composite id, " + "you must implement Equals and GetHashCode.", model.Property.PropertyType.Name)); } if (compositeKeyClassType.IsSerializable == false) { throw new ActiveRecordException(String.Format("To use type '{0}' as a composite id " + "it must be marked as Serializable.", model.Property.PropertyType.Name)); } int keyPropAttrCount = 0; PropertyInfo[] compositeKeyProps = compositeKeyClassType.GetProperties(); foreach (PropertyInfo keyProp in compositeKeyProps) { if (keyProp.GetCustomAttributes(typeof (KeyPropertyAttribute), false).Length > 0) { keyPropAttrCount++; } } if (keyPropAttrCount < 2) { throw new ActiveRecordException(String.Format("To use type '{0}' as a composite " + "id it must have two or more properties marked with the [KeyProperty] attribute.", model.Property.PropertyType.Name)); } }
/// <summary> /// Visits the composite primary key. /// </summary> /// <param name="model">The model.</param> public override void VisitCompositePrimaryKey(CompositeKeyModel model) { CompositeKeyAttribute att = model.CompositeKeyAtt; string unsavedVal = att.UnsavedValue; if (unsavedVal == null) { unsavedVal = "none"; } AppendF("<composite-id{0}{1}{2}{3}>", MakeAtt("name", model.Property.Name), MakeClassAtt(model.Property.PropertyType), WriteIfNonNull("unsaved-value", unsavedVal), MakeAtt("access", att.AccessString)); Ident(); PropertyInfo[] keyProps = model.Property.PropertyType.GetProperties(); foreach(PropertyInfo keyProp in keyProps) { KeyPropertyAttribute keyPropAttr = keyProp.GetCustomAttributes( typeof(KeyPropertyAttribute), false)[0] as KeyPropertyAttribute; if (keyPropAttr.Column == null) { keyPropAttr.Column = keyProp.Name; } AppendF("<key-property{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10} />", MakeAtt("name", keyProp.Name), MakeAtt("access", keyPropAttr.AccessString), MakeAtt("column", keyPropAttr.Column), MakeTypeAtt(keyProp.PropertyType, keyPropAttr.ColumnType), WriteIfNotZero("length", keyPropAttr.Length), WriteIfNonNull("unsaved-value", keyPropAttr.UnsavedValue), WriteIfTrue("not-null", keyPropAttr.NotNull), WriteIfTrue("unique", keyPropAttr.Unique), WriteIfFalse("insert", keyPropAttr.Insert), WriteIfFalse("update", keyPropAttr.Update), WriteIfNonNull("formula", keyPropAttr.Formula)); } Dedent(); AppendF("</composite-id>"); }
/// <summary> /// Visits the composite primary key. /// </summary> /// <param name="model">The model.</param> public virtual void VisitCompositePrimaryKey(CompositeKeyModel model) { }
/// <summary> /// Visits the composite primary key. /// </summary> /// <remarks> /// Validate that the composite key type is implementing GetHashCode() and Equals(), is mark serializable. /// Validate that the compose key is compose of two or more columns /// </remarks> /// <param name="model">The model.</param> public override void VisitCompositePrimaryKey(CompositeKeyModel model) { BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; Type compositeKeyClassType = model.Property.PropertyType; MethodInfo eq = null; MethodInfo hc = null; new List <MethodInfo>(compositeKeyClassType.GetMethods(flags)).ForEach(delegate(MethodInfo method) { if (method.Name.Equals("Equals")) { ParameterInfo[] parameters = method.GetParameters(); if ((parameters.Length == 1) && (parameters[0].ParameterType == typeof(object))) { eq = method; } } else if (method.Name.Equals("GetHashCode")) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 0) { hc = method; } } }); if (eq == null || hc == null) { throw new ActiveRecordException(String.Format("To use type '{0}' as a composite id, " + "you must implement Equals and GetHashCode.", model.Property.PropertyType.Name)); } if (compositeKeyClassType.IsSerializable == false) { throw new ActiveRecordException(String.Format("To use type '{0}' as a composite id " + "it must be marked as Serializable.", model.Property.PropertyType.Name)); } int keyPropAttrCount = 0; PropertyInfo[] compositeKeyProps = compositeKeyClassType.GetProperties(); foreach (PropertyInfo keyProp in compositeKeyProps) { if (keyProp.GetCustomAttributes(typeof(KeyPropertyAttribute), false).Length > 0) { keyPropAttrCount++; } } if (keyPropAttrCount < 2) { throw new ActiveRecordException(String.Format("To use type '{0}' as a composite " + "id it must have two or more properties marked with the [KeyProperty] attribute.", model.Property.PropertyType.Name)); } }