Skip to content

Commit

Permalink
Write to fields by default
Browse files Browse the repository at this point in the history
Fixes #12430
  • Loading branch information
ajcvickers committed Jan 4, 2019
1 parent 4c33bf0 commit 42dd141
Show file tree
Hide file tree
Showing 8 changed files with 339 additions and 98 deletions.
3 changes: 2 additions & 1 deletion src/EFCore/Extensions/ModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ public static ChangeTrackingStrategy GetChangeTrackingStrategy([NotNull] this IM
/// <returns> The access mode being used, or null if the default access mode is being used. </returns>
[DebuggerStepThrough]
public static PropertyAccessMode? GetPropertyAccessMode([NotNull] this IModel model)
=> (PropertyAccessMode?)Check.NotNull(model, nameof(model))[CoreAnnotationNames.PropertyAccessModeAnnotation];
=> (PropertyAccessMode?)Check.NotNull(model, nameof(model))[CoreAnnotationNames.PropertyAccessModeAnnotation]
?? PropertyAccessMode.PreferField;
}
}
10 changes: 5 additions & 5 deletions src/EFCore/Extensions/PropertyBaseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ public static string GetFieldName([NotNull] this IPropertyBase propertyBase)
/// </summary>
/// <param name="propertyBase"> The property for which to get the access mode. </param>
/// <returns> The access mode being used, or null if the default access mode is being used. </returns>
public static PropertyAccessMode? GetPropertyAccessMode(
public static PropertyAccessMode GetPropertyAccessMode(
[NotNull] this IPropertyBase propertyBase)
=> (PropertyAccessMode?)Check.NotNull(propertyBase, nameof(propertyBase))[CoreAnnotationNames.PropertyAccessModeAnnotation]
?? (propertyBase is INavigation
? propertyBase.DeclaringType.GetNavigationAccessMode()
: propertyBase.DeclaringType.GetPropertyAccessMode());
=> (PropertyAccessMode)(Check.NotNull(propertyBase, nameof(propertyBase))[CoreAnnotationNames.PropertyAccessModeAnnotation]
?? (propertyBase is INavigation
? propertyBase.DeclaringType.GetNavigationAccessMode()
: propertyBase.DeclaringType.GetPropertyAccessMode()));
}
}
2 changes: 1 addition & 1 deletion src/EFCore/Metadata/Internal/NavigationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static string ToDebugString([NotNull] this INavigation navigation, bool s
builder.Append(" Inverse: ").Append(navigation.FindInverse().Name);
}

if (navigation.GetPropertyAccessMode() != null)
if (navigation.GetPropertyAccessMode() != PropertyAccessMode.PreferField)
{
builder.Append(" PropertyAccessMode.").Append(navigation.GetPropertyAccessMode());
}
Expand Down
221 changes: 170 additions & 51 deletions src/EFCore/Metadata/Internal/PropertyBaseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Transactions;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
Expand Down Expand Up @@ -130,120 +131,238 @@ public static IClrPropertySetter GetSetter([NotNull] this IPropertyBase property

var propertyInfo = propertyBase.PropertyInfo;
var fieldInfo = propertyBase.FieldInfo;
var setterProperty = propertyInfo?.FindSetterProperty();
var getterProperty = propertyInfo?.FindGetterProperty();

var isCollectionNav = (propertyBase as INavigation)?.IsCollection() == true;
var hasField = fieldInfo != null;
var hasSetter = setterProperty != null;
var hasGetter = getterProperty != null;

var mode = propertyBase.GetPropertyAccessMode();
if (mode == null
|| mode == PropertyAccessMode.FieldDuringConstruction)

if (forConstruction)
{
if (forConstruction)
if (mode == PropertyAccessMode.Field
|| mode == PropertyAccessMode.FieldDuringConstruction)
{
if (fieldInfo != null)
if (hasField)
{
memberInfo = fieldInfo;
return true;
}

if (mode == PropertyAccessMode.FieldDuringConstruction)
if (isCollectionNav)
{
if (!isCollectionNav)
{
errorMessage = GetNoFieldErrorMessage(propertyBase);
return false;
}

return true;
}

errorMessage = GetNoFieldErrorMessage(propertyBase);
return false;
}

if (forSet)
if (mode == PropertyAccessMode.Property)
{
var setterProperty = propertyInfo?.FindSetterProperty();
if (setterProperty != null)
if (hasSetter)
{
memberInfo = setterProperty;
return true;
}

if (fieldInfo != null)
if (isCollectionNav)
{
memberInfo = fieldInfo;
return true;
}

if (!isCollectionNav)
errorMessage = hasGetter
? CoreStrings.NoSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(),nameof(PropertyAccessMode))
: CoreStrings.NoProperty(fieldInfo?.Name,propertyBase.DeclaringType.DisplayName(),nameof(PropertyAccessMode));

return false;
}

if (mode == PropertyAccessMode.PreferField
|| mode == PropertyAccessMode.PreferFieldDuringConstruction)
{
if (hasField)
{
errorMessage = CoreStrings.NoFieldOrSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
return false;
memberInfo = fieldInfo;
return true;
}

return true;
if (hasSetter)
{
memberInfo = setterProperty;
return true;
}
}

var getterPropertyInfo = propertyInfo?.FindGetterProperty();
if (getterPropertyInfo != null)
if (mode == PropertyAccessMode.PreferProperty)
{
memberInfo = getterPropertyInfo;
return true;
if (hasSetter)
{
memberInfo = setterProperty;
return true;
}

if (hasField)
{
memberInfo = fieldInfo;
return true;
}
}

if (fieldInfo != null)
if (isCollectionNav)
{
memberInfo = fieldInfo;
return true;
}

errorMessage = CoreStrings.NoFieldOrGetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
errorMessage = CoreStrings.NoFieldOrSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
return false;
}

if (mode == PropertyAccessMode.Field)
if (forSet)
{
if (fieldInfo == null)
if (mode == PropertyAccessMode.Field)
{
if (hasField)
{
memberInfo = fieldInfo;
return true;
}

if (isCollectionNav)
{
return true;
}

errorMessage = GetNoFieldErrorMessage(propertyBase);
return false;
}

if (mode == PropertyAccessMode.Property)
{
if (!forSet
|| !isCollectionNav)
if (hasSetter)
{
memberInfo = setterProperty;
return true;
}

if (isCollectionNav)
{
errorMessage = GetNoFieldErrorMessage(propertyBase);
return false;
return true;
}

errorMessage = hasGetter
? CoreStrings.NoSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode))
: CoreStrings.NoProperty(fieldInfo?.Name,propertyBase.DeclaringType.DisplayName(),nameof(PropertyAccessMode));

return false;
}

if (mode == PropertyAccessMode.PreferField)
{
if (hasField)
{
memberInfo = fieldInfo;
return true;
}

if (hasSetter)
{
memberInfo = setterProperty;
return true;
}
}

if (mode == PropertyAccessMode.PreferProperty
|| mode == PropertyAccessMode.FieldDuringConstruction
|| mode == PropertyAccessMode.PreferFieldDuringConstruction)
{
if (hasSetter)
{
memberInfo = setterProperty;
return true;
}

if (hasField)
{
memberInfo = fieldInfo;
return true;
}
}

if (isCollectionNav)
{
return true;
}

memberInfo = fieldInfo;
return true;
errorMessage = CoreStrings.NoFieldOrSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
return false;
}

if (propertyInfo == null)
// forGet
if (mode == PropertyAccessMode.Field)
{
errorMessage = CoreStrings.NoProperty(fieldInfo.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));
if (hasField)
{
memberInfo = fieldInfo;
return true;
}

errorMessage = GetNoFieldErrorMessage(propertyBase);
return false;
}

if (forSet)
if (mode == PropertyAccessMode.Property)
{
var setterProperty = propertyInfo.FindSetterProperty();
if (setterProperty == null
&& !isCollectionNav)
if (hasGetter)
{
errorMessage = CoreStrings.NoSetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));
return false;
memberInfo = getterProperty;
return true;
}

memberInfo = setterProperty;
return true;
errorMessage = hasSetter
? CoreStrings.NoGetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode))
: CoreStrings.NoProperty(fieldInfo?.Name,propertyBase.DeclaringType.DisplayName(),nameof(PropertyAccessMode));

return false;
}

var getterProperty = propertyInfo.FindGetterProperty();
if (getterProperty == null)
if (mode == PropertyAccessMode.PreferField)
{
errorMessage = CoreStrings.NoGetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName(), nameof(PropertyAccessMode));
return false;
if (hasField)
{
memberInfo = fieldInfo;
return true;
}

if (hasGetter)
{
memberInfo = getterProperty;
return true;
}
}

if (mode == PropertyAccessMode.PreferProperty
|| mode == PropertyAccessMode.FieldDuringConstruction
|| mode == PropertyAccessMode.PreferFieldDuringConstruction)
{
if (hasGetter)
{
memberInfo = getterProperty;
return true;
}

if (hasField)
{
memberInfo = fieldInfo;
return true;
}
}

memberInfo = getterProperty;
return true;
errorMessage = CoreStrings.NoFieldOrGetter(propertyBase.Name, propertyBase.DeclaringType.DisplayName());
return false;
}

private static string GetNoFieldErrorMessage(IPropertyBase propertyBase)
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/Metadata/Internal/PropertyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ public static string ToDebugString([NotNull] this IProperty property, bool singl
builder.Append(" Ansi");
}

if (property.GetPropertyAccessMode() != null)
if (property.GetPropertyAccessMode() != PropertyAccessMode.PreferField)
{
builder.Append(" PropertyAccessMode.").Append(property.GetPropertyAccessMode());
}
Expand Down
Loading

0 comments on commit 42dd141

Please sign in to comment.