diff --git a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessor.cs b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessor.cs index 2ed07ecfe..ba12933f8 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessor.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessor.cs @@ -4,40 +4,23 @@ // Created by: Alex Yakunin // Created: 2010.02.19 -using System; -using System.Diagnostics; using Xtensive.Core; using Xtensive.Orm.Model; -namespace Xtensive.Orm.Internals -{ - internal abstract class FieldAccessor - { - private FieldInfo fld; - - public FieldInfo Field { - get { return fld; } - set { - if (fld !=null) - throw Exceptions.AlreadyInitialized("Field"); - fld = value; - } - } - - public object DefaultUntypedValue { get; private set; } - - public abstract bool AreSameValues(object oldValue, object newValue); +namespace Xtensive.Orm.Internals; - public abstract void SetUntypedValue(Persistent obj, object value); - - public abstract object GetUntypedValue(Persistent obj); +internal abstract class FieldAccessor(object defaultUntypedValue) +{ + protected ColNum FieldIndex; + public object DefaultUntypedValue { get; } = defaultUntypedValue; - // Constructors - - protected FieldAccessor(object defaultUntypedValue) - { - DefaultUntypedValue = defaultUntypedValue; - } + public virtual void SetFieldInfo(FieldInfo value) + { + FieldIndex = FieldIndex == 0 ? value.MappingInfo.Offset : throw Exceptions.AlreadyInitialized("Field"); } + + public abstract bool AreSameValues(object oldValue, object newValue); + public abstract void SetUntypedValue(Persistent obj, object value); + public abstract object GetUntypedValue(Persistent obj); } diff --git a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessorProvider.cs b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessorProvider.cs index 63f5d236e..35c2e0a0e 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessorProvider.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessorProvider.cs @@ -56,8 +56,8 @@ private static FieldAccessor CreateFieldAccessor(Type accessorType, FieldInfo fi accessorType.CachedMakeGenericType(field.ValueType), BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Array.Empty(), null); - accessor.Field = field; + accessor.SetFieldInfo(field); return accessor; } } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/CachingFieldAccessor.cs b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/CachingFieldAccessor.cs index 91780d522..5953f3bcb 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/CachingFieldAccessor.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/CachingFieldAccessor.cs @@ -4,20 +4,21 @@ // Created by: Dmitri Maximov // Created: 2009.07.08 -using System; +using Xtensive.Core; using Xtensive.Orm.Model; -namespace Xtensive.Orm.Internals.FieldAccessors +namespace Xtensive.Orm.Internals.FieldAccessors; + +internal abstract class CachingFieldAccessor : FieldAccessor { - internal abstract class CachingFieldAccessor : FieldAccessor - { - public static Func Constructor; + public static Func Constructor; + + protected FieldInfo Field; - public override T GetValue(Persistent obj) - { - var field = Field; - var valueAdapter = obj.GetFieldValueAdapter(field, Constructor); - return (T) valueAdapter; - } + public override void SetFieldInfo(FieldInfo value) { + Field = Field is null ? value : throw Exceptions.AlreadyInitialized("Field"); + base.SetFieldInfo(value); } -} \ No newline at end of file + + public override T GetValue(Persistent obj) => (T) obj.GetFieldValueAdapter(Field, Constructor); +} diff --git a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/DefaultFieldAccessor.cs b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/DefaultFieldAccessor.cs index 68bcf6982..4640e39f4 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/DefaultFieldAccessor.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/DefaultFieldAccessor.cs @@ -4,7 +4,6 @@ // Created by: Alexey Gamzov // Created: 2008.05.26 -using System; using Xtensive.Reflection; namespace Xtensive.Orm.Internals.FieldAccessors @@ -32,17 +31,11 @@ public override bool AreSameValues(object oldValue, object newValue) } /// - public override T GetValue(Persistent obj) - { - var fieldIndex = Field.MappingInfo.Offset; - var tuple = obj.Tuple; - var value = tuple.GetValueOrDefault(fieldIndex); - return value; - } + public override T GetValue(Persistent obj) => obj.Tuple.GetValueOrDefault(FieldIndex); /// /// Invalid arguments. public override void SetValue(Persistent obj, T value) => - obj.Tuple.SetValue(Field.MappingInfo.Offset, value); + obj.Tuple.SetValue(FieldIndex, value); } } diff --git a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/EntityFieldAccessor.cs b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/EntityFieldAccessor.cs index 826c8f15c..04f12f68c 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/EntityFieldAccessor.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/EntityFieldAccessor.cs @@ -4,54 +4,48 @@ // Created by: Alexey Gamzov // Created: 2008.05.26 -using System; - +using Xtensive.Core; +using Xtensive.Orm.Model; using Xtensive.Tuples; namespace Xtensive.Orm.Internals.FieldAccessors { internal class EntityFieldAccessor : FieldAccessor { - /// - public override bool AreSameValues(object oldValue, object newValue) + private FieldInfo field; + + public override void SetFieldInfo(FieldInfo value) { - return ReferenceEquals(oldValue, newValue); + field = field is null ? value : throw Exceptions.AlreadyInitialized("Field"); + base.SetFieldInfo(value); } + + /// + public override bool AreSameValues(object oldValue, object newValue) => ReferenceEquals(oldValue, newValue); /// /// Invalid arguments. public override void SetValue(Persistent obj, T value) { - var entity = value as Entity; - var field = Field; + var tuple = obj.Tuple; + if (value is Entity entity) { + if (entity.Session != obj.Session) + throw new InvalidOperationException(string.Format(Strings.ExEntityXIsBoundToAnotherSession, entity.Key)); - if (!ReferenceEquals(value, null) && entity==null) - throw new InvalidOperationException(string.Format( - Strings.ExValueShouldBeXDescendant, WellKnownOrmTypes.Entity)); - - if (entity!=null && entity.Session!=obj.Session) - throw new InvalidOperationException(string.Format( - Strings.ExEntityXIsBoundToAnotherSession, entity.Key)); - - var mappingInfo = field.MappingInfo; - int fieldIndex = mappingInfo.Offset; - if (entity==null) { - int nextFieldIndex = fieldIndex + mappingInfo.Length; - for (int i = fieldIndex; i < nextFieldIndex; i++) - obj.Tuple.SetValue(i, null); + entity.Key.Value.CopyTo(tuple, 0, FieldIndex, field.MappingInfo.Length); } else { - entity.Key.Value.CopyTo(obj.Tuple, 0, fieldIndex, mappingInfo.Length); + if (!ReferenceEquals(value, null)) + throw new InvalidOperationException(string.Format(Strings.ExValueShouldBeXDescendant, WellKnownOrmTypes.Entity)); + + for (int i = FieldIndex, nextFieldIndex = FieldIndex + field.MappingInfo.Length; i < nextFieldIndex; i++) + tuple.SetValue(i, null); } } /// - public override T GetValue(Persistent obj) - { - var field = Field; - Key key = obj.GetReferenceKey(field); - if (key is null) - return default(T); - return (T) (object) obj.Session.Query.SingleOrDefault(key); - } + public override T GetValue(Persistent obj) => + obj.GetReferenceKey(field) is { } key + ? (T) (object) obj.Session.Query.SingleOrDefault(key) + : default; } } diff --git a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/EnumFieldAccessor.cs b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/EnumFieldAccessor.cs index 87d7ecb36..67714be11 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/EnumFieldAccessor.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/EnumFieldAccessor.cs @@ -4,7 +4,7 @@ // Created by: Alexey Gamzov // Created: 2008.06.07 -using System; +using Xtensive.Orm.Model; using Xtensive.Reflection; using Xtensive.Tuples; @@ -18,6 +18,14 @@ internal sealed class EnumFieldAccessor : FieldAccessor ? (type.IsNullable() ? null : Enum.GetValues(type).GetValue(0)) : default(T); + private Type columnValueType; + + public override void SetFieldInfo(FieldInfo value) + { + columnValueType = value.Column.ValueType; + base.SetFieldInfo(value); + } + /// public override bool AreSameValues(object oldValue, object newValue) { @@ -27,25 +35,17 @@ public override bool AreSameValues(object oldValue, object newValue) /// public override T GetValue(Persistent obj) { - var field = Field; - int fieldIndex = field.MappingInfo.Offset; - var tuple = obj.Tuple; - - TupleFieldState state; - var value = tuple.GetValue(fieldIndex, out state); - if (!state.HasValue()) - return (T) @default; - if (type.IsEnum) - return (T) Enum.ToObject(type, value); - return (T) Enum.ToObject(Nullable.GetUnderlyingType(type), value); + var value = obj.Tuple.GetValue(FieldIndex, out var state); + return (T) (!state.HasValue() ? @default + : type.IsEnum ? Enum.ToObject(type, value) + : Enum.ToObject(Nullable.GetUnderlyingType(type), value)); } /// public override void SetValue(Persistent obj, T value) { - var field = Field; // Biconverter converter = GetConverter(field.ValueType); - obj.Tuple.SetValue(field.MappingInfo.Offset, value==null ? null : Convert.ChangeType(value, field.Column.ValueType)); + obj.Tuple.SetValue(FieldIndex, value==null ? null : Convert.ChangeType(value, columnValueType)); } } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/KeyFieldAccessor.cs b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/KeyFieldAccessor.cs index 88a89062e..83a39f7a4 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/KeyFieldAccessor.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/KeyFieldAccessor.cs @@ -4,41 +4,27 @@ // Created by: Alex Yakunin // Created: 2008.11.21 -using System; using Xtensive.Tuples; -using Tuple = Xtensive.Tuples.Tuple; -namespace Xtensive.Orm.Internals.FieldAccessors -{ - internal class KeyFieldAccessor : FieldAccessor - { - private static readonly T @default = default; +namespace Xtensive.Orm.Internals.FieldAccessors; - /// - public override bool AreSameValues(object oldValue, object newValue) - { - return object.Equals(oldValue, newValue); - } +internal class KeyFieldAccessor : FieldAccessor +{ + /// + public override bool AreSameValues(object oldValue, object newValue) => Equals(oldValue, newValue); - /// - public override T GetValue(Persistent obj) - { - var field = Field; - int fieldIndex = field.MappingInfo.Offset; - var tuple = obj.Tuple; - TupleFieldState state; - var value = tuple.GetValue(fieldIndex, out state); - if (!state.IsAvailable()) - return @default; - return (T) (object) Key.Parse(obj.Session.Domain, value); - } + /// + public override T GetValue(Persistent obj) + { + var value = obj.Tuple.GetValue(FieldIndex, out var state); + return !state.IsAvailable() + ? default + : (T) (object) Key.Parse(obj.Session.Domain, value); + } - /// - public override void SetValue(Persistent obj, T value) - { - var field = Field; - var key = (Key) (object) value; - obj.Tuple.SetValue(field.MappingInfo.Offset, key is null ? null : key.Format()); - } + /// + public override void SetValue(Persistent obj, T value) + { + obj.Tuple.SetValue(FieldIndex, ((Key) (object) value)?.Format()); } } diff --git a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/StructureFieldAccessor.cs b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/StructureFieldAccessor.cs index 5b0ff92ec..648fbac9f 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/StructureFieldAccessor.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessors/StructureFieldAccessor.cs @@ -4,9 +4,6 @@ // Created by: Dmitri Maximov // Created: 2008.05.30 -using System; -using Xtensive.Core; - using Xtensive.Tuples; namespace Xtensive.Orm.Internals.FieldAccessors @@ -14,25 +11,21 @@ namespace Xtensive.Orm.Internals.FieldAccessors internal sealed class StructureFieldAccessor : CachingFieldAccessor { /// - public override bool AreSameValues(object oldValue, object newValue) - { - return oldValue.Equals(newValue); - } + public override bool AreSameValues(object oldValue, object newValue) => oldValue.Equals(newValue); + /// public override void SetValue(Persistent obj, T value) { - var field = Field; ArgumentNullException.ThrowIfNull(value); var valueType = value.GetType(); - if (field.ValueType != valueType) + if (Field.ValueType != valueType) throw new InvalidOperationException(String.Format( - Strings.ExResultTypeIncorrect, valueType.Name, field.ValueType.Name)); + Strings.ExResultTypeIncorrect, valueType.Name, Field.ValueType.Name)); var structure = (Structure) (object) value; var adapter = (IFieldValueAdapter)value; - if (adapter.Owner!=null) - adapter.Owner.EnsureIsFetched(adapter.Field); - structure.Tuple.CopyTo(obj.Tuple, 0, field.MappingInfo.Offset, field.MappingInfo.Length); + adapter.Owner?.EnsureIsFetched(adapter.Field); + structure.Tuple.CopyTo(obj.Tuple, 0, FieldIndex, Field.MappingInfo.Length); } // Type initializer @@ -42,4 +35,4 @@ static StructureFieldAccessor() Constructor = (obj, field) => Activator.CreateStructure(field.ValueType, obj, field); } } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessor{T}.cs b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessor{T}.cs index 4c83a9b52..afa9722ab 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/FieldAccessor{T}.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/FieldAccessor{T}.cs @@ -4,37 +4,13 @@ // Created by: Alexey Gamzov // Created: 2008.06.02 -using System; -using Xtensive.Orm.Model; +namespace Xtensive.Orm.Internals; - -namespace Xtensive.Orm.Internals +internal abstract class FieldAccessor() : FieldAccessor(default(T)) { - internal abstract class FieldAccessor : FieldAccessor - { - public T DefaultValue { get; private set; } - - public abstract void SetValue(Persistent obj, T value); - - public abstract T GetValue(Persistent obj); - - public override void SetUntypedValue(Persistent obj, object value) - { - SetValue(obj, (T) value); - } - - public override object GetUntypedValue(Persistent obj) - { - return GetValue(obj); - } - + public abstract void SetValue(Persistent obj, T value); + public override void SetUntypedValue(Persistent obj, object value) => SetValue(obj, (T) value); - // Constructors - - protected FieldAccessor() - : base(default(T)) - { - DefaultValue = default(T); - } - } -} \ No newline at end of file + public abstract T GetValue(Persistent obj); + public override object GetUntypedValue(Persistent obj) => GetValue(obj); +}