private void InitSpecialMember(MetaDataMember mm) { // Can only have one auto gen member that is also an identity member, // except if that member is a computed column (since they are implicitly auto gen) if(mm.IsDbGenerated && mm.IsPrimaryKey && string.IsNullOrEmpty(mm.Expression)) { if(this.dbGeneratedIdentity != null) throw Error.TwoMembersMarkedAsPrimaryKeyAndDBGenerated(mm.Member, this.dbGeneratedIdentity.Member); this.dbGeneratedIdentity = mm; } if(mm.IsPrimaryKey && !MappingSystem.IsSupportedIdentityType(mm.Type)) { throw Error.IdentityClrTypeNotSupported(mm.DeclaringType, mm.Name, mm.Type); } if(mm.IsVersion) { if(this.version != null) throw Error.TwoMembersMarkedAsRowVersion(mm.Member, this.version.Member); this.version = mm; } if(mm.IsDiscriminator) { if(this.discriminator != null) throw Error.TwoMembersMarkedAsInheritanceDiscriminator(mm.Member, this.discriminator.Member); this.discriminator = mm; } }
public AttributedMetaAssociation(MemberInfo member, AssociationAttribute attribute, MetaDataMember metaDataMember) { memberInfo = member; associationAttribute = attribute; thisMember = metaDataMember; Load(); }
internal MemberChangeConflict(ObjectChangeConflict conflict, MetaDataMember metaMember) { this.conflict = conflict; this.metaMember = metaMember; this.originalValue = metaMember.StorageAccessor.GetBoxedValue(conflict.Original); this.databaseValue = metaMember.StorageAccessor.GetBoxedValue(conflict.Database); this.currentValue = metaMember.StorageAccessor.GetBoxedValue(conflict.TrackedObject.Current); }
public virtual void SetOtherKey(string literalOtherKey, MetaTable thisTable, MetaTable otherTable, MetaDataMember otherAssociationMember) { var comma = new[] { ',' }; var otherKeysList = new List<MetaDataMember>(); if (literalOtherKey != null) { foreach (var otherKeyRaw in literalOtherKey.Split(comma, StringSplitOptions.RemoveEmptyEntries)) { var otherKey = otherKeyRaw.Trim(); //we need to revisit this code - it has caused problems on both MySql and Pgsql MemberInfo[] otherKeyFields = otherTable.RowType.Type.GetMember(otherKey); if (otherKeyFields.Length == 0) { string msg = "ERROR L57 Database contains broken join information." + " thisTable=" + thisTable.TableName + " otherTable=" + otherTable.TableName + " orphanKey=" + literalOtherKey; throw new InvalidOperationException(msg); } var keyMember = otherKeyFields[0]; otherKeysList.Add(new AttributedColumnMetaDataMember(keyMember, GetColumnAttribute(keyMember), thisTable.RowType)); } } otherKeys = new ReadOnlyCollection<MetaDataMember>(otherKeysList); otherMember = otherAssociationMember; }
private void ValidatePrimaryKeyMember(MetaDataMember mm) { //if the type is a sub-type, no member in the type can be primary key if(mm.IsPrimaryKey && this.inheritanceRoot != this && mm.Member.DeclaringType == this.type) { throw (Error.PrimaryKeyInSubTypeNotSupported(this.type.Name, mm.Name)); } }
private void ValidatePrimaryKeyMember(MetaDataMember metaDataMember) { // if the type is a sub-type, no member declared in the type can be primary key if (metaDataMember.IsPrimaryKey && inheritanceRoot != this && metaDataMember.Member.DeclaringType == type) { throw Error.PrimaryKeyInSubTypeNotSupported(type.Name, metaDataMember.Name); } }
private void ValidatePrimaryKeyMember(MetaDataMember mm) { //if the type is a sub-type, no member in the type can be primary key if (mm.IsPrimaryKey && this.inheritanceRoot != this && mm.Member.DeclaringType == this.type) { throw (Error.PrimaryKeyInSubTypeNotSupported(this.type.Name, mm.Name)); } }
internal AttributedMetaAssociation(AttributedMetaDataMember member, AssociationAttribute attr) { thisMember = member; isMany = TypeSystem.IsSequenceType(thisMember.Type); var otherEntityType = isMany ? TypeSystem.GetElementType(thisMember.Type) : thisMember.Type; otherType = thisMember.DeclaringType.Model.GetMetaType(otherEntityType); thisKey = attr.ThisKey == null ? thisMember.DeclaringType.IdentityMembers : MakeKeys(thisMember.DeclaringType, attr.ThisKey); otherKey = attr.OtherKey == null ? otherType.IdentityMembers : MakeKeys(otherType, attr.OtherKey); thisKeyIsPrimaryKey = AreEqual(thisKey, thisMember.DeclaringType.IdentityMembers); otherKeyIsPrimaryKey = AreEqual(otherKey, otherType.IdentityMembers); isForeignKey = attr.IsForeignKey; isUnique = attr.IsUnique; deleteRule = attr.DeleteRule; deleteOnNull = attr.DeleteOnNull; // if any key members are not nullable, the association is not nullable isNullable = true; foreach (var thisKeyMember in thisKey) { if (!thisKeyMember.CanBeNull) { isNullable = false; break; } } // validate DeleteOnNull specification if (deleteOnNull && (!isForeignKey || isMany || isNullable)) { throw Error.InvalidDeleteOnNullSpecification(member); } if ((thisKey.Count != otherKey.Count) && (thisKey.Count > 0) && (otherKey.Count > 0)) { throw Error.MismatchedThisKeyOtherKey(member.Name, member.DeclaringType.Name); } // determine reverse reference member foreach (var otherTypePersistentMember in otherType.PersistentDataMembers) { var otherTypeMemberAssociationAttribute = ((AttributedMetaModel)thisMember.DeclaringType.Model) .TryGetAssociationAttribute(otherTypePersistentMember.Member); if ((otherTypeMemberAssociationAttribute != null) && (otherTypePersistentMember != thisMember) && (otherTypeMemberAssociationAttribute.Name == attr.Name)) { otherMember = otherTypePersistentMember; break; } } //validate the number of ThisKey columns is the same as the number of OtherKey columns }
public ColumnExpression(TableExpression table, MetaDataMember metaData) : base(ExpressionType, metaData.Member.GetMemberType()) // memberInfo.GetMemberType()) { Table = table; Name = metaData.MappedName; MemberInfo = metaData.Member; StorageInfo = metaData.StorageMember; RequestIndex = -1; // unused }
internal AttributedMetaAssociation(AttributedMetaDataMember member, AssociationAttribute attr) { this.thisMember = member; this.isMany = TypeSystem.IsSequenceType(this.thisMember.Type); Type ot = this.isMany ? TypeSystem.GetElementType(this.thisMember.Type) : this.thisMember.Type; this.otherType = this.thisMember.DeclaringType.Model.GetMetaType(ot); this.thisKey = (attr.ThisKey != null) ? MakeKeys(this.thisMember.DeclaringType, attr.ThisKey) : this.thisMember.DeclaringType.IdentityMembers; this.otherKey = (attr.OtherKey != null) ? MakeKeys(otherType, attr.OtherKey) : this.otherType.IdentityMembers; this.thisKeyIsPrimaryKey = AreEqual(this.thisKey, this.thisMember.DeclaringType.IdentityMembers); this.otherKeyIsPrimaryKey = AreEqual(this.otherKey, this.otherType.IdentityMembers); this.isForeignKey = attr.IsForeignKey; this.isUnique = attr.IsUnique; this.deleteRule = attr.DeleteRule; this.deleteOnNull = attr.DeleteOnNull; // if any key members are not nullable, the association is not nullable foreach (MetaDataMember mm in thisKey) { if (!mm.CanBeNull) { this.isNullable = false; break; } } // validate DeleteOnNull specification if (deleteOnNull == true) { if (!(isForeignKey && !isMany && !isNullable)) { throw Error.InvalidDeleteOnNullSpecification(member); } } //validate the number of ThisKey columns is the same as the number of OtherKey columns if (this.thisKey.Count != this.otherKey.Count && this.thisKey.Count > 0 && this.otherKey.Count > 0) { throw Error.MismatchedThisKeyOtherKey(member.Name, member.DeclaringType.Name); } // determine reverse reference member foreach (MetaDataMember omm in this.otherType.PersistentDataMembers) { AssociationAttribute oattr = (AssociationAttribute)Attribute.GetCustomAttribute(omm.Member, typeof(AssociationAttribute)); if (oattr != null) { if (omm != this.thisMember && oattr.Name == attr.Name) { this.otherMember = omm; break; } } } }
internal AttributedMetaAssociation(AttributedMetaDataMember member, AssociationAttribute attr) { this.thisMember = member; this.isMany = TypeSystem.IsSequenceType(this.thisMember.Type); Type ot = this.isMany ? TypeSystem.GetElementType(this.thisMember.Type) : this.thisMember.Type; this.otherType = this.thisMember.DeclaringType.Model.GetMetaType(ot); this.thisKey = (attr.ThisKey != null) ? MakeKeys(this.thisMember.DeclaringType, attr.ThisKey) : this.thisMember.DeclaringType.IdentityMembers; this.otherKey = (attr.OtherKey != null) ? MakeKeys(otherType, attr.OtherKey) : this.otherType.IdentityMembers; this.thisKeyIsPrimaryKey = AreEqual(this.thisKey, this.thisMember.DeclaringType.IdentityMembers); this.otherKeyIsPrimaryKey = AreEqual(this.otherKey, this.otherType.IdentityMembers); this.isForeignKey = attr.IsForeignKey; this.isUnique = attr.IsUnique; this.deleteRule = attr.DeleteRule; this.deleteOnNull = attr.DeleteOnNull; // if any key members are not nullable, the association is not nullable foreach(MetaDataMember mm in thisKey) { if(!mm.CanBeNull) { this.isNullable = false; break; } } // validate DeleteOnNull specification if(deleteOnNull == true) { if(!(isForeignKey && !isMany && !isNullable)) { throw Error.InvalidDeleteOnNullSpecification(member); } } //validate the number of ThisKey columns is the same as the number of OtherKey columns if(this.thisKey.Count != this.otherKey.Count && this.thisKey.Count > 0 && this.otherKey.Count > 0) { throw Error.MismatchedThisKeyOtherKey(member.Name, member.DeclaringType.Name); } // determine reverse reference member foreach(MetaDataMember omm in this.otherType.PersistentDataMembers) { AssociationAttribute oattr = (AssociationAttribute)Attribute.GetCustomAttribute(omm.Member, typeof(AssociationAttribute)); if(oattr != null) { if(omm != this.thisMember && oattr.Name == attr.Name) { this.otherMember = omm; break; } } } }
internal SqlLink(object id, MetaType rowType, Type clrType, ProviderType sqlType, SqlExpression expression, MetaDataMember member, IEnumerable<SqlExpression> keyExpressions, SqlExpression expansion, Expression sourceExpression) : base(SqlNodeType.Link, clrType, sqlType, sourceExpression) { this.id = id; this.rowType = rowType; this.expansion = expansion; this.expression = expression; this.member = member; this.keyExpressions = new List<SqlExpression>(); if (keyExpressions != null) this.keyExpressions.AddRange(keyExpressions); }
public DLinqColumnProvider (TableProvider owner, MetaDataMember meta) : base (owner) { if (owner == null) throw new ArgumentNullException ("owner"); if (meta == null) throw new ArgumentNullException ("meta"); // FIXME: fill more Name = meta.Name; Nullable = meta.CanBeNull; }
/// <summary> /// Returns an AssociationAttribute for the specified association member /// </summary> /// <param name="member">The metadata member corresponding to the association member</param> /// <returns>The Association attribute</returns> public System.ComponentModel.DataAnnotations.AssociationAttribute CreateAssociationAttribute(MetaDataMember member) { MetaAssociation metaAssociation = member.Association; string associationName = this.GetAssociationName(metaAssociation); string thisKey = TypeDescriptionContextBase.FormatMemberList(metaAssociation.ThisKey.Select(p => p.Name)); string otherKey = TypeDescriptionContextBase.FormatMemberList(metaAssociation.OtherKey.Select(p => p.Name)); System.ComponentModel.DataAnnotations.AssociationAttribute assocAttrib = new System.ComponentModel.DataAnnotations.AssociationAttribute(associationName, thisKey, otherKey); assocAttrib.IsForeignKey = metaAssociation.IsForeignKey; return assocAttrib; }
internal SqlColumn(Type clrType, ProviderType sqlType, string name, MetaDataMember member, SqlExpression expr, Expression sourceExpression) : base(SqlNodeType.Column, clrType, sourceExpression) { if (typeof(Type).IsAssignableFrom(clrType)) throw Error.ArgumentWrongValue("clrType"); this.Name = name; this.member = member; this.Expression = expr; this.Ordinal = -1; if (sqlType == null) throw Error.ArgumentNull("sqlType"); this.sqlType = sqlType; System.Diagnostics.Debug.Assert(sqlType.CanBeColumn); }
public DLinqColumnProvider(DLinqTableProvider table, MetaDataMember member) : base(table) { Member = member; Name = member.Name; ColumnType = GetMemberType(member); IsPrimaryKey = member.IsPrimaryKey; IsGenerated = member.IsDbGenerated; _isAssociation = member.IsAssociation; IsCustomProperty = !member.IsAssociation && Member.DbType == null; Nullable = Member.IsAssociation ? Member.Association.IsNullable : Member.CanBeNull; MaxLength = ProcessMaxLength(ColumnType, Member.DbType); IsSortable = ProcessIsSortable(ColumnType, Member.DbType); }
private void AddColumn(DLinqDataModelProvider dataModel, MetaDataMember member, PropertyInfo propInfo) { var publicGetAccessor = propInfo.GetGetMethod(); if (publicGetAccessor == null) { // the property at least needs to have a public getter, otherwise databinding will not work return; } DLinqColumnProvider column = new DLinqColumnProvider(this, member); _columns.Add(column); if (!dataModel.ColumnLookup.ContainsKey(propInfo)) dataModel.ColumnLookup[propInfo] = column; }
public AttributedMetaAssociation(MemberInfo member, AssociationAttribute attribute, MetaDataMember metaDataMember) { _memberInfo = member; _associationAttribute = attribute; _thisMember = metaDataMember; // The bug described here: // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=376669 // says that under certain conditions, there's a bug where _otherMember == _thisMember // Not only is there no point in reproducing a MS bug, it's not as simple as simply setting _otherMember = metaDataMember Type otherType = _memberInfo.GetFirstInnerReturnType(); string associationName = member.GetAttribute<AssociationAttribute>().Name; AttributedMetaType ownedMetaType = metaDataMember.DeclaringType.Model.GetMetaType(otherType) as AttributedMetaType; if ( ownedMetaType == null ) throw new InvalidOperationException("Key in referenced table is of a different SQL MetaData provider"); _otherMember = ownedMetaType.AssociationsLookup[otherType.GetMembers().Where(m => (AttributeNameNullCheck(m.GetAttribute<AssociationAttribute>()) == associationName) && (m != member)).Single()]; }
/// <summary> /// Given a MetaType and a set of key fields, return the set of MetaDataMembers /// corresponding to the key. /// </summary> protected static ReadOnlyCollection<MetaDataMember> MakeKeys(MetaType mtype, string keyFields) { string[] names = keyFields.Split(keySeparators); MetaDataMember[] members = new MetaDataMember[names.Length]; for(int i = 0; i < names.Length; i++) { names[i] = names[i].Trim(); MemberInfo[] rmis = mtype.Type.GetMember(names[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if(rmis == null || rmis.Length != 1) { throw Error.BadKeyMember(names[i], keyFields, mtype.Name); } members[i] = mtype.GetDataMember(rmis[0]); if(members[i] == null) { throw Error.BadKeyMember(names[i], keyFields, mtype.Name); } } return new List<MetaDataMember>(members).AsReadOnly(); }
/// <summary> /// Given a MetaType and a set of key fields, return the set of MetaDataMembers /// corresponding to the key. /// </summary> protected static ReadOnlyCollection <MetaDataMember> MakeKeys(MetaType mtype, string keyFields) { string[] names = keyFields.Split(keySeparators); MetaDataMember[] members = new MetaDataMember[names.Length]; for (int i = 0; i < names.Length; i++) { names[i] = names[i].Trim(); MemberInfo[] rmis = mtype.Type.GetMember(names[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (rmis == null || rmis.Length != 1) { throw Error.BadKeyMember(names[i], keyFields, mtype.Name); } members[i] = mtype.GetDataMember(rmis[0]); if (members[i] == null) { throw Error.BadKeyMember(names[i], keyFields, mtype.Name); } } return(new List <MetaDataMember>(members).AsReadOnly()); }
private void InitOther() { if (this.otherType == null) { Type ot = this.isMany ? TypeSystem.GetElementType(this.thisMember.Type) : this.thisMember.Type; this.otherType = this.thisMember.DeclaringType.Model.GetMetaType(ot); System.Diagnostics.Debug.Assert(this.otherType.IsEntity); this.otherKey = (assocMap.OtherKey != null) ? MakeKeys(this.otherType, this.assocMap.OtherKey) : this.otherType.IdentityMembers; this.otherKeyIsPrimaryKey = AreEqual(this.otherKey, this.otherType.IdentityMembers); foreach (MetaDataMember omm in this.otherType.DataMembers) { if (omm.IsAssociation && omm != this.thisMember && omm.MappedName == this.thisMember.MappedName) { this.otherMember = omm; break; } } } }
public string CreateColomnSQL( MetaTable table, MetaDataMember member) { StringBuilder sqlText = new StringBuilder(); if (member.IsPrimaryKey) { sqlText.AppendFormat("{0} INTEGER PRIMARY KEY AUTOINCREMENT ", member.MappedName); } else { sqlText.AppendFormat("{0} {1} ", member.MappedName, member.DbType); } if (!member.CanBeNull) { sqlText.Append("NOT NULL"); } return sqlText.ToString(); }
public string CreateColomnSQL( MetaTable table, MetaDataMember member) { StringBuilder sqlText = new StringBuilder(); sqlText.AppendFormat("{0} {1} ", member.MappedName, FilterDBType(member.DbType)); if (member.IsPrimaryKey) { sqlText.AppendFormat("IDENTITY(1,1) CONSTRAINT PK_{0} PRIMARY KEY CLUSTERED ", table.TableName); } // TODO: Foreign key associations if (!member.CanBeNull) { sqlText.Append("NOT NULL"); } return sqlText.ToString(); }
public override MetaDataMember GetDataMember(MemberInfo mi) { if(mi == null) throw Error.ArgumentNull("mi"); MetaDataMember mm = null; if(this.dataMemberMap.TryGetValue(new MetaPosition(mi), out mm)) { return mm; } else { // DON'T look to see if we are trying to get a member from an inherited type. // The calling code should know to look in the inherited type. if(mi.DeclaringType.IsInterface) { throw Error.MappingOfInterfacesMemberIsNotSupported(mi.DeclaringType.Name, mi.Name); } else { //the member is not mapped in the base class throw Error.UnmappedClassMember(mi.DeclaringType.Name, mi.Name); } } }
/// <summary> /// Provides the parameter type for a given data member /// </summary> /// <param name="objectToUpsert"></param> /// <param name="dataMember"></param> /// <param name="update"></param> /// <returns></returns> protected virtual ParameterType GetParameterType(object objectToUpsert, MetaDataMember dataMember, bool update) { var memberInfo = dataMember.Member; // the deal with columns is: // PK only: explicit for INSERT, criterion for UPDATE // PK+GEN: implicit/explicit for INSERT, criterion for UPDATE // GEN only: implicit for both // -: explicit for both // // explicit is input, // implicit is output, // criterion is input PK ParameterType type; if (dataMember.IsPrimaryKey) { if (update) type = ParameterType.InputPK; else { if (dataMember.IsDbGenerated) { if (IsSpecified(objectToUpsert, memberInfo)) type = ParameterType.Input; else type = ParameterType.Output; } else type = ParameterType.Input; } } else { if (dataMember.IsDbGenerated) type = ParameterType.Output; else type = ParameterType.Input; } return type; }
internal abstract bool IsMemberPendingGeneration(MetaDataMember keyMember);
private static Type GetMemberType(MetaDataMember member) { Type type = member.Type; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(EntitySet<>)) { return type.GetGenericArguments()[0]; } else { return type; } }
internal SqlMember Member(SqlExpression expr, MetaDataMember member) { return new SqlMember(member.Type, this.Default(member), expr, member.Member); }
private void GenerateAssignValue(MetaDataMember mm, LocalBuilder locInstance, SqlExpression expr, LocalBuilder locStoreInMember) { MemberInfo m = mm.StorageMember != null ? mm.StorageMember : mm.Member; if(!IsAssignable(m)) { throw Error.CannotAssignToMember(m.Name); } Type memberType = TypeSystem.GetMemberType(m); Label labExit = gen.DefineLabel(); bool hasSideEffect = this.HasSideEffect(expr); if(locStoreInMember != null && !hasSideEffect) { gen.Emit(OpCodes.Ldloc, locStoreInMember); this.GenerateConstInt(0); gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Brtrue, labExit); } this.GenerateExpressionForType(expr, memberType, mm.DeclaringType.IsEntity ? locInstance : null); LocalBuilder locValue = gen.DeclareLocal(memberType); gen.Emit(OpCodes.Stloc, locValue); if(locStoreInMember != null && hasSideEffect) { gen.Emit(OpCodes.Ldloc, locStoreInMember); this.GenerateConstInt(0); gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Brtrue, labExit); } this.GenerateLoadForMemberAccess(locInstance); gen.Emit(OpCodes.Ldloc, locValue); this.GenerateStoreMember(m); gen.MarkLabel(labExit); }
private bool IsDbGeneratedKeyProjectionOnly(Expression projection, MetaDataMember keyMember) { NewArrayExpression array = projection as NewArrayExpression; if (array != null && array.Expressions.Count == 1) { Expression exp = array.Expressions[0]; while (exp.NodeType == ExpressionType.Convert || exp.NodeType == ExpressionType.ConvertChecked) { exp = ((UnaryExpression)exp).Operand; } MemberExpression mex = exp as MemberExpression; if (mex != null && mex.Member == keyMember.Member) { return true; } } return false; }
private void InitSpecialMember(MetaDataMember mm) { // Can only have one auto gen member that is also an identity member, // except if that member is a computed column (since they are implicitly auto gen) if (mm.IsDbGenerated && mm.IsPrimaryKey && string.IsNullOrEmpty(mm.Expression)) { if (this.dbGeneratedIdentity != null) throw Error.TwoMembersMarkedAsPrimaryKeyAndDBGenerated(mm.Member, this.dbGeneratedIdentity.Member); this.dbGeneratedIdentity = mm; } if (mm.IsPrimaryKey && !MappingSystem.IsSupportedIdentityType(mm.Type)) { throw Error.IdentityClrTypeNotSupported(mm.DeclaringType, mm.Name, mm.Type); } if (mm.IsVersion) { if (this.version != null) throw Error.TwoMembersMarkedAsRowVersion(mm.Member, this.version.Member); this.version = mm; } if (mm.IsDiscriminator) { if (this.discriminator!=null) throw Error.TwoMembersMarkedAsInheritanceDiscriminator(mm.Member, this.discriminator.Member); this.discriminator = mm; } }
internal ProviderType Default(MetaDataMember member) { if(member == null) throw Error.ArgumentNull("member"); if (member.DbType != null) { return this.typeProvider.Parse(member.DbType); } else { return this.typeProvider.From(member.Type); } }
private static string GetDbType(MetaDataMember mm) { string dbType = mm.DbType; if(dbType != null) return dbType; StringBuilder sb = new StringBuilder(); Type type = mm.Type; bool isNullable = mm.CanBeNull; if(type.IsValueType && IsNullable(type)) { type = type.GetGenericArguments()[0]; } if(mm.IsVersion) { sb.Append("Timestamp"); } else { if(mm.IsPrimaryKey && mm.IsDbGenerated) { switch(Type.GetTypeCode(type)) { case TypeCode.Byte: sb.Append("TinyInt"); break; case TypeCode.SByte: case TypeCode.Int16: sb.Append("SmallInt"); break; case TypeCode.Int32: case TypeCode.UInt16: sb.Append("Int"); break; case TypeCode.Int64: case TypeCode.UInt32: sb.Append("BigInt"); break; case TypeCode.UInt64: case TypeCode.Decimal: sb.Append("Decimal(20)"); break; case TypeCode.Object: if(type == typeof(Guid)) { sb.Append("UniqueIdentifier"); } else { throw Error.CouldNotDetermineDbGeneratedSqlType(type); } break; } } else { switch(Type.GetTypeCode(type)) { case TypeCode.Boolean: sb.Append("Bit"); break; case TypeCode.Byte: sb.Append("TinyInt"); break; case TypeCode.SByte: case TypeCode.Int16: sb.Append("SmallInt"); break; case TypeCode.Int32: case TypeCode.UInt16: sb.Append("Int"); break; case TypeCode.Int64: case TypeCode.UInt32: sb.Append("BigInt"); break; case TypeCode.UInt64: sb.Append("Decimal(20)"); break; case TypeCode.Decimal: sb.Append("Decimal(29, 4)"); break; case TypeCode.Double: sb.Append("Float"); break; case TypeCode.Single: sb.Append("Real"); break; case TypeCode.Char: sb.Append("NChar(1)"); break; case TypeCode.String: sb.Append("NVarChar(4000)"); break; case TypeCode.DateTime: sb.Append("DateTime"); break; case TypeCode.Object: if(type == typeof(Guid)) { sb.Append("UniqueIdentifier"); } else if(type == typeof(byte[])) { sb.Append("VarBinary(8000)"); } else if(type == typeof(char[])) { sb.Append("NVarChar(4000)"); } else if(type == typeof(DateTimeOffset)) { sb.Append("DateTimeOffset"); } else if(type == typeof(TimeSpan)) { sb.Append("Time"); } else { throw Error.CouldNotDetermineSqlType(type); } break; } } } if(!isNullable) { sb.Append(" NOT NULL"); } if(mm.IsPrimaryKey && mm.IsDbGenerated) { if(type == typeof(Guid)) { sb.Append(" DEFAULT NEWID()"); } else { sb.Append(" IDENTITY"); } } return sb.ToString(); }
private void GenerateAssignDeferredReference(MetaDataMember mm, LocalBuilder locInstance, SqlExpression expr, LocalBuilder locStoreInMember) { MemberInfo m = mm.StorageMember != null ? mm.StorageMember : mm.Member; Type memberType = TypeSystem.GetMemberType(m); Diagnostics.Debug.Assert( memberType.IsGenericType && (memberType.GetGenericTypeDefinition() == typeof(EntityRef<>) || memberType.GetGenericTypeDefinition() == typeof(Link<>)) ); Label labExit = gen.DefineLabel(); Type argType = typeof(IEnumerable<>).MakeGenericType(memberType.GetGenericArguments()); bool hasSideEffect = this.HasSideEffect(expr); if(locStoreInMember != null && !hasSideEffect) { gen.Emit(OpCodes.Ldloc, locStoreInMember); this.GenerateConstInt(0); gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Brtrue, labExit); } Type eType = this.GenerateDeferredSource(expr, locInstance); if(!argType.IsAssignableFrom(eType)) { throw Error.CouldNotConvert(argType, eType); } LocalBuilder locSource = gen.DeclareLocal(eType); gen.Emit(OpCodes.Stloc, locSource); if(locStoreInMember != null && hasSideEffect) { gen.Emit(OpCodes.Ldloc, locStoreInMember); this.GenerateConstInt(0); gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Brtrue, labExit); } this.GenerateLoadForMemberAccess(locInstance); gen.Emit(OpCodes.Ldloc, locSource); ConstructorInfo ci = memberType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { argType }, null); Diagnostics.Debug.Assert(ci != null); gen.Emit(OpCodes.Newobj, ci); this.GenerateStoreMember(m); gen.MarkLabel(labExit); }
private void GenerateAssignEntitySet(MetaDataMember mm, LocalBuilder locInstance, SqlExpression expr, LocalBuilder locStoreInMember) { MemberInfo m = mm.StorageMember != null ? mm.StorageMember : mm.Member; Type memberType = TypeSystem.GetMemberType(m); Diagnostics.Debug.Assert(memberType.IsGenericType && memberType.GetGenericTypeDefinition() == typeof(EntitySet<>)); Label labExit = gen.DefineLabel(); Type argType = typeof(IEnumerable<>).MakeGenericType(memberType.GetGenericArguments()); bool hasSideEffect = this.HasSideEffect(expr); if(locStoreInMember != null && !hasSideEffect) { gen.Emit(OpCodes.Ldloc, locStoreInMember); this.GenerateConstInt(0); gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Brtrue, labExit); } Type eType = this.Generate(expr, mm.DeclaringType.IsEntity ? locInstance : null); Diagnostics.Debug.Assert(argType.IsAssignableFrom(eType)); LocalBuilder locSource = gen.DeclareLocal(eType); gen.Emit(OpCodes.Stloc, locSource); if(locStoreInMember != null && hasSideEffect) { gen.Emit(OpCodes.Ldloc, locStoreInMember); this.GenerateConstInt(0); gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Brtrue, labExit); } // if member is directly writeable, check for null entityset if(m is FieldInfo || (m is PropertyInfo && ((PropertyInfo)m).CanWrite)) { Label labFetch = gen.DefineLabel(); this.GenerateLoadForMemberAccess(locInstance); this.GenerateLoadMember(m); gen.Emit(OpCodes.Ldnull); gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Brfalse, labFetch); // create new entity set this.GenerateLoadForMemberAccess(locInstance); ConstructorInfo ci = memberType.GetConstructor(System.Type.EmptyTypes); Diagnostics.Debug.Assert(ci != null); gen.Emit(OpCodes.Newobj, ci); this.GenerateStoreMember(m); gen.MarkLabel(labFetch); } // set the source this.GenerateLoadForMemberAccess(locInstance); this.GenerateLoadMember(m); gen.Emit(OpCodes.Ldloc, locSource); MethodInfo miAssign = memberType.GetMethod("Assign", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { argType }, null); Diagnostics.Debug.Assert(miAssign != null); gen.Emit(GetMethodCallOpCode(miAssign), miAssign); gen.MarkLabel(labExit); }
private SqlExpression GetIdentityExpression(MetaDataMember id, bool isOutputFromInsert) { if (isOutputFromInsert) { return new SqlVariable(id.Type, sql.Default(id), "@id", this.dominatingExpression); } else { ProviderType sqlType = sql.Default(id); if (!IsLegalIdentityType(sqlType.GetClosestRuntimeType())) { throw Error.InvalidDbGeneratedType(sqlType.ToQueryString()); } if ((this.converterStrategy & ConverterStrategy.CanUseScopeIdentity) != 0) { return new SqlVariable(typeof(decimal), typeProvider.From(typeof(decimal)), "SCOPE_IDENTITY()", this.dominatingExpression); } else { return new SqlVariable(typeof(decimal), typeProvider.From(typeof(decimal)), "@@IDENTITY", this.dominatingExpression); } } }
private void GenerateMemberAssignment(MetaDataMember mm, LocalBuilder locInstance, SqlExpression expr, LocalBuilder locStoreInMember) { MemberInfo m = mm.StorageMember != null ? mm.StorageMember : mm.Member; Type memberType = TypeSystem.GetMemberType(m); // check for deferrable member & deferred source expression if(IsDeferrableExpression(expr) && (this.compiler.Services.Context.LoadOptions == null || !this.compiler.Services.Context.LoadOptions.IsPreloaded(mm.Member)) ) { // we can only defer deferrable members if(mm.IsDeferred) { // determine at runtime if we are allowed to defer load gen.Emit(OpCodes.Ldarg_0); Type orbType = typeof(ObjectMaterializer<>).MakeGenericType(this.compiler.DataReaderType); PropertyInfo piCanDeferLoad = orbType.GetProperty("CanDeferLoad"); Diagnostics.Debug.Assert(piCanDeferLoad != null); MethodInfo miCanDeferLoad = piCanDeferLoad.GetGetMethod(); gen.Emit(GetMethodCallOpCode(miCanDeferLoad), miCanDeferLoad); // if we can't defer load then jump over the code that does the defer loading Label labEndDeferLoad = gen.DefineLabel(); gen.Emit(OpCodes.Brfalse, labEndDeferLoad); // execute the defer load operation if(memberType.IsGenericType) { Type genType = memberType.GetGenericTypeDefinition(); if(genType == typeof(EntitySet<>)) { this.GenerateAssignDeferredEntitySet(mm, locInstance, expr, locStoreInMember); } else if(genType == typeof(EntityRef<>) || genType == typeof(Link<>)) { this.GenerateAssignDeferredReference(mm, locInstance, expr, locStoreInMember); } else { throw Error.DeferredMemberWrongType(); } } else { throw Error.DeferredMemberWrongType(); } gen.MarkLabel(labEndDeferLoad); } else { // behavior for non-deferred members w/ deferrable expressions is to load nothing } } else if(memberType.IsGenericType && memberType.GetGenericTypeDefinition() == typeof(EntitySet<>)) { this.GenerateAssignEntitySet(mm, locInstance, expr, locStoreInMember); } else { this.GenerateAssignValue(mm, locInstance, expr, locStoreInMember); } }