public AttributedColumnMetaDataMember(MemberInfo member, ColumnAttribute attribute, MetaType declaringType) : base(member, declaringType, attribute) { columnAttribute = attribute; if (columnAttribute.Name == null) columnAttribute.Name = memberInfo.Name; }
internal PropertyData(PropertyInfo pi) { this.PropertyInfo = pi; ColumnAttribute = ReflectionHelper.GetAttributes<ColumnAttribute>(pi, true).FirstOrDefault(); FqlFieldName = GetLinqFieldName(); IsLinqIdentity = GetIsLinqIdentity(); }
public AttributedColumnMetaDataMember(MemberInfo member, ColumnAttribute attribute, MetaType declaringType) : base(member, declaringType, member.DeclaringType.GetSingleMember(attribute.Storage)) { columnAttribute = attribute; if (columnAttribute.Name == null) columnAttribute.Name = memberInfo.Name; }
internal AttributedMetaDataMember(AttributedMetaType metaType, MemberInfo mi, int ordinal) { this.declaringType = mi.DeclaringType; this.metaType = metaType; this.member = mi; this.ordinal = ordinal; this.type = TypeSystem.GetMemberType(mi); this.isNullableType = TypeSystem.IsNullableType(this.type); this.attrColumn = (ColumnAttribute)Attribute.GetCustomAttribute(mi, typeof(ColumnAttribute)); this.attrAssoc = (AssociationAttribute)Attribute.GetCustomAttribute(mi, typeof(AssociationAttribute)); this.attr = (this.attrColumn != null) ? (DataAttribute)this.attrColumn : (DataAttribute)this.attrAssoc; if(this.attr != null && this.attr.Storage != null) { MemberInfo[] mis = mi.DeclaringType.GetMember(this.attr.Storage, BindingFlags.Instance | BindingFlags.NonPublic); if(mis == null || mis.Length != 1) { throw Error.BadStorageProperty(this.attr.Storage, mi.DeclaringType, mi.Name); } this.storageMember = mis[0]; } Type storageType = this.storageMember != null ? TypeSystem.GetMemberType(this.storageMember) : this.type; this.isDeferred = IsDeferredType(storageType); if(attrColumn != null && attrColumn.IsDbGenerated && attrColumn.IsPrimaryKey) { // auto-gen identities must be synced on insert if((attrColumn.AutoSync != AutoSync.Default) && (attrColumn.AutoSync != AutoSync.OnInsert)) { throw Error.IncorrectAutoSyncSpecification(mi.Name); } } }
public void Ctor() { var c = new ColumnAttribute(); Assert.AreEqual(AutoSync.Default, c.AutoSync); Assert.AreEqual(true, c.CanBeNull); Assert.AreEqual(null, c.DbType); Assert.AreEqual(null, c.Expression); Assert.AreEqual(false, c.IsDbGenerated); Assert.AreEqual(false, c.IsDiscriminator); Assert.AreEqual(false, c.IsVersion); Assert.AreEqual(UpdateCheck.Always, c.UpdateCheck); Assert.AreEqual(false, c.IsPrimaryKey); Assert.AreEqual(null, c.Name); Assert.AreEqual(null, c.Storage); Assert.AreEqual(c.GetType(), c.TypeId); }
private static void CopyAttributeToMapping(ColumnAttribute attribute, IColumnMapping mapping) { if (attribute == null) return; if (attribute.IsDbGenerated) mapping.DbGenerated(); if (attribute.IsPrimaryKey) mapping.PrimaryKey(); if (attribute.IsVersion) mapping.Version(); if (!attribute.CanBeNull) mapping.NotNull(); if (!string.IsNullOrEmpty(attribute.DbType)) mapping.DbType(attribute.DbType); if (!string.IsNullOrEmpty(attribute.Name)) mapping.Named(attribute.Name); if (!string.IsNullOrEmpty(attribute.Expression)) mapping.Expression(attribute.Expression); if (!string.IsNullOrEmpty(attribute.Storage)) mapping.Storage(attribute.Storage); mapping.AutoSync(attribute.AutoSync); mapping.UpdateCheck(attribute.UpdateCheck); //TODO: Discriminator }
/// <summary> /// Writes property accessor /// </summary> /// <param name="writer"></param> /// <param name="property"></param> /// <param name="relatedAssociations"></param> /// <param name="context"></param> protected virtual void WriteClassPropertyAccessors(CodeWriter writer, Column property, IEnumerable<Association> relatedAssociations, GenerationContext context) { //generate [Column(...)] attribute var column = NewAttributeDefinition<ColumnAttribute>(); column["Storage"] = property.Storage; column["Name"] = property.Name; column["DbType"] = property.DbType; // be smart: we only write attributes when they differ from the default values var columnAttribute = new ColumnAttribute(); if (property.IsPrimaryKey != columnAttribute.IsPrimaryKey) column["IsPrimaryKey"] = property.IsPrimaryKey; if (property.IsDbGenerated != columnAttribute.IsDbGenerated) column["IsDbGenerated"] = property.IsDbGenerated; if (property.AutoSync != DbLinq.Schema.Dbml.AutoSync.Default) column["AutoSync"] = new EnumFullname("AutoSync", property.AutoSync); if (property.CanBeNull != columnAttribute.CanBeNull) column["CanBeNull"] = property.CanBeNull; if (property.Expression != null) column["Expression"] = property.Expression; var specifications = property.AccessModifierSpecified ? GetSpecificationDefinition(property.AccessModifier) : SpecificationDefinition.Public; if (property.ModifierSpecified) specifications |= GetSpecificationDefinition(property.Modifier); //using (WriteAttributes(writer, context.Parameters.MemberExposedAttributes)) using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.MemberAttributes))) using (writer.WriteAttribute(NewAttributeDefinition<DebuggerNonUserCodeAttribute>())) using (writer.WriteAttribute(column)) using (writer.WriteProperty(specifications, property.Member, GetTypeOrExtendedType(writer, property))) { // on auto storage, we're just lazy if (property.Storage == null) writer.WriteAutomaticPropertyGetSet(); else { using (writer.WritePropertyGet()) { writer.WriteLine(writer.GetReturnStatement(writer.GetVariableExpression(property.Storage))); } using (writer.WritePropertySet()) { WriteClassPropertyAccessorSet(writer, property, relatedAssociations, context); } } } }
protected CodeTypeDeclaration GenerateTableClass(Table table, Database database) { var _class = new CodeTypeDeclaration() { IsClass = true, IsPartial = true, Name = table.Type.Name, TypeAttributes = TypeAttributes.Public, CustomAttributes = { new CodeAttributeDeclaration("Table", new CodeAttributeArgument("Name", new CodePrimitiveExpression(table.Name))), }, }; WriteCustomTypes(_class, table); var havePrimaryKeys = table.Type.Columns.Any(c => c.IsPrimaryKey); if (havePrimaryKeys) { GenerateINotifyPropertyChanging(_class); GenerateINotifyPropertyChanged(_class); } // Implement Constructor var constructor = new CodeConstructor() { Attributes = MemberAttributes.Public }; // children are EntitySet foreach (var child in GetClassChildren(table)) { // if the association has a storage, we use it. Otherwise, we use the property name var entitySetMember = GetStorageFieldName(child); constructor.Statements.Add( new CodeAssignStatement( new CodeVariableReferenceExpression(entitySetMember), new CodeObjectCreateExpression( new CodeTypeReference("EntitySet", new CodeTypeReference(child.Type)), new CodeDelegateCreateExpression( new CodeTypeReference("Action", new CodeTypeReference(child.Type)), thisReference, child.Member + "_Attach"), new CodeDelegateCreateExpression( new CodeTypeReference("Action", new CodeTypeReference(child.Type)), thisReference, child.Member + "_Detach")))); } constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); _class.Members.Add(constructor); if (Context.Parameters.GenerateEqualsHash) { GenerateEntityGetHashCodeAndEquals(_class, table); } GenerateExtensibilityDeclarations(_class, table); // todo: add these when the actually get called //partial void OnLoaded(); //partial void OnValidate(System.Data.Linq.ChangeAction action); // columns foreach (Column column in table.Type.Columns) { var relatedAssociations = from a in table.Type.Associations where a.IsForeignKey && a.TheseKeys.Contains(column.Name) select a; var type = ToCodeTypeReference(column); var columnMember = column.Member ?? column.Name; var field = new CodeMemberField(type, GetStorageFieldName(column)); _class.Members.Add(field); var fieldReference = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name); var onChanging = GetChangingMethodName(columnMember); var onChanged = GetChangedMethodName(columnMember); var property = new CodeMemberProperty(); property.Type = type; property.Name = columnMember; property.Attributes = MemberAttributes.Public | MemberAttributes.Final; var defAttrValues = new ColumnAttribute(); var args = new List<CodeAttributeArgument>() { new CodeAttributeArgument("Storage", new CodePrimitiveExpression(GetStorageFieldName(column))), new CodeAttributeArgument("Name", new CodePrimitiveExpression(column.Name)), new CodeAttributeArgument("DbType", new CodePrimitiveExpression(column.DbType)), }; if (defAttrValues.IsPrimaryKey != column.IsPrimaryKey) args.Add(new CodeAttributeArgument("IsPrimaryKey", new CodePrimitiveExpression(column.IsPrimaryKey))); if (defAttrValues.IsDbGenerated != column.IsDbGenerated) args.Add(new CodeAttributeArgument("IsDbGenerated", new CodePrimitiveExpression(column.IsDbGenerated))); if (column.AutoSync != DbLinq.Schema.Dbml.AutoSync.Default) args.Add(new CodeAttributeArgument("AutoSync", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("AutoSync"), column.AutoSync.ToString()))); if (defAttrValues.CanBeNull != column.CanBeNull) args.Add(new CodeAttributeArgument("CanBeNull", new CodePrimitiveExpression(column.CanBeNull))); if (column.Expression != null) args.Add(new CodeAttributeArgument("Expression", new CodePrimitiveExpression(column.Expression))); property.CustomAttributes.Add( new CodeAttributeDeclaration("Column", args.ToArray())); property.CustomAttributes.Add(new CodeAttributeDeclaration("DebuggerNonUserCode")); property.GetStatements.Add(new CodeMethodReturnStatement(fieldReference)); var whenUpdating = new List<CodeStatement>( from assoc in relatedAssociations select (CodeStatement) new CodeConditionStatement( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(GetStorageFieldName(assoc)), "HasLoadedOrAssignedValue"), new CodeThrowExceptionStatement( new CodeObjectCreateExpression(typeof(System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException))))); whenUpdating.Add( new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, onChanging, new CodePropertySetValueReferenceExpression()))); if (havePrimaryKeys) whenUpdating.Add( new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "SendPropertyChanging"))); whenUpdating.Add( new CodeAssignStatement(fieldReference, new CodePropertySetValueReferenceExpression())); if (havePrimaryKeys) whenUpdating.Add( new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "SendPropertyChanged", new CodePrimitiveExpression(property.Name)))); whenUpdating.Add( new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, onChanged))); var fieldType = TypeLoader.Load(column.Type); // This is needed for VB.NET generation; // int/string/etc. can use '<>' for comparison, but NOT arrays and other reference types. // arrays/etc. require the 'Is' operator, which is CodeBinaryOperatorType.IdentityEquality. // The VB IsNot operator is not exposed from CodeDom. // Thus, we need to special-case: if fieldType is a ref or nullable type, // generate '(field Is value) = false'; otherwise, // generate '(field <> value)' CodeBinaryOperatorExpression condition = fieldType.IsClass || fieldType.IsNullable() ? ValuesAreNotEqual_Ref(new CodeVariableReferenceExpression(field.Name), new CodePropertySetValueReferenceExpression()) : ValuesAreNotEqual(new CodeVariableReferenceExpression(field.Name), new CodePropertySetValueReferenceExpression()); property.SetStatements.Add(new CodeConditionStatement(condition, whenUpdating.ToArray())); _class.Members.Add(property); } GenerateEntityChildren(_class, table, database); GenerateEntityChildrenAttachment(_class, table, database); GenerateEntityParents(_class, table, database); return _class; }
/// <summary> /// Gets the length limit for a given field on a LINQ object ... or zero if not known /// </summary> /// <remarks> /// You can use the results from this method to dynamically /// set the allowed length of an INPUT on your web page to /// exactly the same length as the length of the database column. /// Change the database and the UI changes just by /// updating your DBML and recompiling. /// </remarks> public static int GetLengthLimit(ColumnAttribute ca) { if (ca == null) { return int.MaxValue; } int dblenint = 0; // default value = we can't determine the length string dbtype = ca.DbType; if (dbtype.StartsWith("NChar") || dbtype.StartsWith("NVarChar")) { int index1 = dbtype.IndexOf("("); int index2 = dbtype.IndexOf(")"); string dblen = dbtype.Substring(index1 + 1, index2 - index1 - 1); if (dblen == "MAX") { return int.MaxValue; } int.TryParse(dblen, out dblenint); } return dblenint; }