internal StandardTrackedObject(StandardChangeTracker tracker, MetaType type, object current, object original) { if (current == null) { throw Error.ArgumentNull("current"); } this.tracker = tracker; this.type = type.GetInheritanceType(current.GetType()); this.current = current; this.original = original; this.state = State.PossiblyModified; dirtyMemberCache = new BitArray(this.type.DataMembers.Count); }
private IEnumerable <RelatedItem> GetRelations(MetaType type, object item, bool isForeignKey) { foreach (MetaDataMember mm in type.PersistentDataMembers) { if (mm.IsAssociation) { MetaType otherType = mm.Association.OtherType; if (mm.Association.IsForeignKey == isForeignKey) { object value = null; if (mm.IsDeferred) { value = mm.DeferredValueAccessor.GetBoxedValue(item); } else { value = mm.StorageAccessor.GetBoxedValue(item); } if (value != null) { if (mm.Association.IsMany) { IEnumerable list = (IEnumerable)value; foreach (object otherItem in list) { yield return(new RelatedItem(otherType.GetInheritanceType(otherItem.GetType()), otherItem)); } } else { yield return(new RelatedItem(otherType.GetInheritanceType(value.GetType()), value)); } } } } } }
internal override object CreateDataCopy(object instance) { System.Diagnostics.Debug.Assert(instance != null); Type instanceType = instance.GetType(); System.Diagnostics.Debug.Assert(instance.GetType() == this.type.Type); object copy = Activator.CreateInstance(this.Type.Type); MetaType rootMetaType = this.tracker.services.Model.GetTable(instanceType).RowType.InheritanceRoot; foreach (MetaDataMember mm in rootMetaType.GetInheritanceType(instanceType).PersistentDataMembers) { if (this.Type.Type != instanceType && !mm.DeclaringType.Type.IsAssignableFrom(instanceType)) { continue; } if (mm.IsDeferred) { // do not copy associations if (!mm.IsAssociation) { if (mm.StorageAccessor.HasValue(instance)) { object value = mm.DeferredValueAccessor.GetBoxedValue(instance); mm.DeferredValueAccessor.SetBoxedValue(ref copy, value); } else { IEnumerable ds = this.tracker.services.GetDeferredSourceFactory(mm).CreateDeferredSource(copy); mm.DeferredSourceAccessor.SetBoxedValue(ref copy, ds); } } } else { // otherwise assign the value as-is to the backup instance object value = mm.StorageAccessor.GetBoxedValue(instance); // assumes member values are immutable or will communicate changes to entity // note: byte[] and char[] don't do this. mm.StorageAccessor.SetBoxedValue(ref copy, value); } } return(copy); }
// Methods internal StandardTrackedObject(StandardChangeTracker tracker, MetaType type, object current, object original) { if (current == null) { throw Error.ArgumentNull("current"); } this.tracker = tracker; this.type = type.GetInheritanceType(current.GetType()); this.current = current; this.original = original; state = State.PossiblyModified; //if (type is DynamicMetaType) //{ // //TODO:由于 DynamicMetaType.DataMembers 数量是变值,只能暂时给最个大值, // dirtyMemberCache = new BitArray(DynamicMetaType.MaxDataMembersCount); //} //else dirtyMemberCache = new BitArray(this.type.DataMembers.Count); }
public override MetaType GetInheritanceType(Type type) { return(_orgtype.GetInheritanceType(type)); }
// Return value indicates whether or not any data was actually [....]'d internal override bool SynchDependentData() { bool valueWasSet = false; // set foreign key fields foreach (MetaAssociation assoc in this.Type.Associations) { MetaDataMember mm = assoc.ThisMember; if (assoc.IsForeignKey) { bool hasAssigned = mm.StorageAccessor.HasAssignedValue(this.current); bool hasLoaded = mm.StorageAccessor.HasLoadedValue(this.current); if (hasAssigned || hasLoaded) { object parent = mm.StorageAccessor.GetBoxedValue(this.current); if (parent != null) { // copy parent's current primary key into this instance's foreign key fields for (int i = 0, n = assoc.ThisKey.Count; i < n; i++) { MetaDataMember accThis = assoc.ThisKey[i]; MetaDataMember accParent = assoc.OtherKey[i]; object parentValue = accParent.StorageAccessor.GetBoxedValue(parent); accThis.StorageAccessor.SetBoxedValue(ref this.current, parentValue); valueWasSet = true; } } else if (assoc.IsNullable) { if (mm.IsDeferred || (this.original != null && mm.MemberAccessor.GetBoxedValue(this.original) != null)) { // no known parent? set to null for (int i = 0, n = assoc.ThisKey.Count; i < n; i++) { MetaDataMember accThis = assoc.ThisKey[i]; if (accThis.CanBeNull) { if (this.original != null && this.HasChangedValue(accThis)) { if (accThis.StorageAccessor.GetBoxedValue(this.current) != null) { throw Error.InconsistentAssociationAndKeyChange(accThis.Member.Name, mm.Member.Name); } } else { accThis.StorageAccessor.SetBoxedValue(ref this.current, null); valueWasSet = true; } } } } } else if (!hasLoaded) { //Else the parent association has been set to null; but the ID is not nullable so //the value can not be set StringBuilder keys = new StringBuilder(); foreach (MetaDataMember key in assoc.ThisKey) { if (keys.Length > 0) { keys.Append(", "); } keys.AppendFormat("{0}.{1}", this.Type.Name.ToString(), key.Name); } throw Error.CouldNotRemoveRelationshipBecauseOneSideCannotBeNull(assoc.OtherType.Name, this.Type.Name, keys); } } } } /// Explicitly set any inheritance discriminator for item. if (this.type.HasInheritance) { if (this.original != null) { object currentDiscriminator = type.Discriminator.MemberAccessor.GetBoxedValue(this.current); MetaType currentTypeFromDiscriminator = TypeFromDiscriminator(this.type, currentDiscriminator); object dbDiscriminator = type.Discriminator.MemberAccessor.GetBoxedValue(this.original); MetaType dbTypeFromDiscriminator = TypeFromDiscriminator(this.type, dbDiscriminator); // Would the discriminator change also change the type? If so, its not allowed. if (currentTypeFromDiscriminator != dbTypeFromDiscriminator) { throw Error.CannotChangeInheritanceType(dbDiscriminator, currentDiscriminator, original.GetType().Name, currentTypeFromDiscriminator); } } else { // No db value means this is an 'Add'. Set the discriminator. MetaType currentType = type.GetInheritanceType(this.current.GetType()); if (currentType.HasInheritanceCode) { object code = currentType.InheritanceCode; this.type.Discriminator.MemberAccessor.SetBoxedValue(ref current, code); valueWasSet = true; } } } return(valueWasSet); }
internal override bool SynchDependentData() { var result = false; foreach (var association in Type.Associations) { var thisMember = association.ThisMember; if (association.IsForeignKey) { var flag = thisMember.StorageAccessor.HasAssignedValue(current); var flag2 = thisMember.StorageAccessor.HasLoadedValue(current); if (flag | flag2) { var boxedValue = thisMember.StorageAccessor.GetBoxedValue(current); if (boxedValue != null) { var i = 0; for (var count = association.ThisKey.Count; i < count; i++) { var metaDataMember = association.ThisKey[i]; var metaDataMember2 = association.OtherKey[i]; var boxedValue2 = metaDataMember2.StorageAccessor.GetBoxedValue(boxedValue); metaDataMember.StorageAccessor.SetBoxedValue(ref current, boxedValue2); result = true; } } else if (association.IsNullable) { if (thisMember.IsDeferred || (original != null && thisMember.MemberAccessor.GetBoxedValue(original) != null)) { var j = 0; for (var count2 = association.ThisKey.Count; j < count2; j++) { var metaDataMember3 = association.ThisKey[j]; if (metaDataMember3.CanBeNull) { if (original != null && HasChangedValue(metaDataMember3)) { if (metaDataMember3.StorageAccessor.GetBoxedValue(current) != null) { throw System.Data.Linq.Error.InconsistentAssociationAndKeyChange(metaDataMember3.Member.Name, thisMember.Member.Name); } } else { metaDataMember3.StorageAccessor.SetBoxedValue(ref current, null); result = true; } } } } } else if (!flag2) { var stringBuilder = new StringBuilder(); foreach (var item in association.ThisKey) { if (stringBuilder.Length > 0) { stringBuilder.Append(", "); } stringBuilder.AppendFormat("{0}.{1}", Type.Name.ToString(), item.Name); } throw System.Data.Linq.Error.CouldNotRemoveRelationshipBecauseOneSideCannotBeNull(association.OtherType.Name, Type.Name, stringBuilder); } } } } if (type.HasInheritance) { if (original != null) { var boxedValue3 = type.Discriminator.MemberAccessor.GetBoxedValue(current); var metaType = TypeFromDiscriminator(type, boxedValue3); var boxedValue4 = type.Discriminator.MemberAccessor.GetBoxedValue(original); var metaType2 = TypeFromDiscriminator(type, boxedValue4); if (metaType != metaType2) { throw System.Data.Linq.Error.CannotChangeInheritanceType(boxedValue4, boxedValue3, original.GetType().Name, metaType); } } else { var inheritanceType = type.GetInheritanceType(current.GetType()); if (inheritanceType.HasInheritanceCode) { var inheritanceCode = inheritanceType.InheritanceCode; type.Discriminator.MemberAccessor.SetBoxedValue(ref current, inheritanceCode); result = true; } } } return(result); }
internal override void SynchDependentData() { foreach (MetaAssociation association in Type.Associations) { MetaDataMember thisMember = association.ThisMember; if (association.IsForeignKey) { bool flag = thisMember.StorageAccessor.HasAssignedValue(current); bool flag2 = thisMember.StorageAccessor.HasLoadedValue(current); if (flag || flag2) { object boxedValue = thisMember.StorageAccessor.GetBoxedValue(current); if (boxedValue != null) { int num = 0; int count = association.ThisKey.Count; while (num < count) { MetaDataMember member2 = association.ThisKey[num]; MetaDataMember member3 = association.OtherKey[num]; object obj3 = member3.StorageAccessor.GetBoxedValue(boxedValue); member2.StorageAccessor.SetBoxedValue(ref current, obj3); num++; } continue; } if (association.IsNullable) { if (thisMember.IsDeferred || ((original != null) && (thisMember.MemberAccessor.GetBoxedValue(original) != null))) { int num3 = 0; int num4 = association.ThisKey.Count; while (num3 < num4) { MetaDataMember mm = association.ThisKey[num3]; if (mm.CanBeNull) { if ((original != null) && HasChangedValue(mm)) { if (mm.StorageAccessor.GetBoxedValue(current) != null) { throw Error.InconsistentAssociationAndKeyChange(mm.Member.Name, thisMember. Member.Name); } } else { mm.StorageAccessor.SetBoxedValue(ref current, null); } } num3++; } } continue; } if (!flag2) { var builder = new StringBuilder(); foreach (MetaDataMember member5 in association.ThisKey) { if (builder.Length > 0) { builder.Append(", "); } builder.AppendFormat("{0}.{1}", Type.Name, member5.Name); } throw Error.CouldNotRemoveRelationshipBecauseOneSideCannotBeNull( association.OtherType.Name, Type.Name, builder); } } } } if (type.HasInheritance) { if (original != null) { object discriminator = type.Discriminator.MemberAccessor.GetBoxedValue(current); MetaType t = TypeFromDiscriminator(type, discriminator); object obj5 = type.Discriminator.MemberAccessor.GetBoxedValue(original); MetaType type2 = TypeFromDiscriminator(type, obj5); if (t != type2) { throw Error.CannotChangeInheritanceType(obj5, discriminator, original.GetType().Name, t); } } else { MetaType inheritanceType = type.GetInheritanceType(current.GetType()); if (inheritanceType.HasInheritanceCode) { object inheritanceCode = inheritanceType.InheritanceCode; type.Discriminator.MemberAccessor.SetBoxedValue(ref current, inheritanceCode); } } } }