Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
maumar committed Dec 12, 2019
2 parents c556df0 + d3214e2 commit af8ff54
Show file tree
Hide file tree
Showing 45 changed files with 949 additions and 794 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static IServiceCollection AddEntityFrameworkDesignTimeServices(
.AddSingleton<IScaffoldingModelFactory, RelationalScaffoldingModelFactory>()
.AddSingleton<IScaffoldingTypeMapper, ScaffoldingTypeMapper>()
.AddSingleton<IValueConverterSelector, ValueConverterSelector>()
.AddSingleton<ISimpleLogger, NullSimpleLogger>()
.AddSingleton<IDbContextLogger, NullDbContextLogger>()
.AddTransient<MigrationsScaffolderDependencies>()
.AddTransient<IMigrationsScaffolder, MigrationsScaffolder>()
.AddTransient<ISnapshotModelProcessor, SnapshotModelProcessor>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2217,7 +2217,7 @@ private static TransactionEventData BroadcasstTransactionUsed(
if (simpleLogEnabled)
{
diagnostics.SimpleLogger.Log(eventData);
diagnostics.DbContextLogger.Log(eventData);
}
return eventData;
Expand Down
13 changes: 0 additions & 13 deletions src/EFCore/ChangeTracking/ChangeTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;

Expand Down Expand Up @@ -397,18 +396,6 @@ Task IResettableService.ResetStateAsync(CancellationToken cancellationToken)
return default;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
[EntityFrameworkInternal]
public virtual DebugView DebugView
=> new DebugView(
() => StateManager.ToDebugString(StateManagerDebugStringOptions.ShortDefault),
() => StateManager.ToDebugString(StateManagerDebugStringOptions.LongDefault));

#region Hidden System.Object members

/// <summary>
Expand Down
7 changes: 3 additions & 4 deletions src/EFCore/ChangeTracking/EntityEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -403,14 +403,13 @@ private void Reload(PropertyValues storeValues)
private IEntityFinder Finder
=> InternalEntry.StateManager.CreateEntityFinder(InternalEntry.EntityType);

#region Hidden System.Object members

/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns> A string that represents the current object. </returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString();
public override string ToString() => InternalEntry.ToString();

#region Hidden System.Object members

/// <summary>
/// Determines whether the specified object is equal to the current object.
Expand Down
196 changes: 194 additions & 2 deletions src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Storage;
Expand Down Expand Up @@ -1673,8 +1676,197 @@ public virtual bool IsLoaded([NotNull] INavigation navigation)
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override string ToString()
=> $"{this.BuildCurrentValuesString(EntityType.FindPrimaryKey().Properties)} {EntityState}"
+ $"{(((IUpdateEntry)this).SharedIdentityEntry == null ? "" : " Shared")} {EntityType}";
=> ToDebugString(StateManagerDebugStringOptions.ShortDefault);

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual DebugView DebugView
=> new DebugView(
() => this.ToDebugString(StateManagerDebugStringOptions.ShortDefault),
() => this.ToDebugString(StateManagerDebugStringOptions.LongDefault));

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual string ToDebugString(StateManagerDebugStringOptions options)
{
var builder = new StringBuilder();
var keyString = this.BuildCurrentValuesString(EntityType.FindPrimaryKey().Properties);

builder
.Append(EntityType.DisplayName())
.Append(' ')
.Append(SharedIdentityEntry == null ? "(Shared) " : "")
.Append(keyString)
.Append(' ')
.Append(EntityState.ToString());

if ((options & StateManagerDebugStringOptions.IncludeProperties) != 0)
{
foreach (var property in EntityType.GetProperties())
{
builder.AppendLine();

var currentValue = GetCurrentValue(property);
builder
.Append(" ")
.Append(property.Name)
.Append(": ");

AppendValue(currentValue);

if (property.IsPrimaryKey())
{
builder.Append(" PK");
}
else if (property.IsKey())
{
builder.Append(" AK");
}

if (property.IsForeignKey())
{
builder.Append(" FK");
}

if (IsModified(property))
{
builder.Append(" Modified");
}

if (HasTemporaryValue(property))
{
builder.Append(" Temporary");
}

if (HasOriginalValuesSnapshot
&& property.GetOriginalValueIndex() != -1)
{
var originalValue = GetOriginalValue(property);
if (!Equals(originalValue, currentValue))
{
builder.Append(" Originally ");
AppendValue(originalValue);
}
}
}
}
else
{
foreach (var alternateKey in EntityType.GetKeys().Where(k => !k.IsPrimaryKey()))
{
builder
.Append(" AK ")
.Append(this.BuildCurrentValuesString(alternateKey.Properties));
}

foreach (var foreignKey in EntityType.GetForeignKeys())
{
builder
.Append(" FK ")
.Append(this.BuildCurrentValuesString(foreignKey.Properties));
}
}

if ((options & StateManagerDebugStringOptions.IncludeNavigations) != 0)
{
foreach (var navigation in EntityType.GetNavigations())
{
builder.AppendLine();

var currentValue = GetCurrentValue(navigation);
var targetType = navigation.GetTargetType();

builder
.Append(" ")
.Append(navigation.Name)
.Append(": ");

if (currentValue == null)
{
builder.Append("<null>");
}
else if (navigation.IsCollection())
{
builder.Append('[');

const int maxRelatedToShow = 32;
var relatedEntities = ((IEnumerable)currentValue).Cast<object>().Take(maxRelatedToShow + 1).ToList();

for (var i = 0; i < relatedEntities.Count; i++)
{
if (i != 0)
{
builder.Append(", ");
}

if (i < 32)
{
AppendRelatedKey(targetType, relatedEntities[i]);
}
else
{
builder.Append("...");
}
}

builder.Append(']');
}
else
{
AppendRelatedKey(targetType, currentValue);
}
}
}

return builder.ToString();

void AppendValue(object value)
{
if (value == null)
{
builder.Append("<null>");
}
else if (value.GetType().IsNumeric())
{
builder.Append(value);
}
else if (value is byte[] bytes)
{
builder.AppendBytes(bytes);
}
else
{
var stringValue = value.ToString();
if (stringValue.Length > 63)
{
stringValue = stringValue.Substring(0, 60) + "...";
}

builder
.Append('\'')
.Append(stringValue)
.Append('\'');
}
}

void AppendRelatedKey(IEntityType targetType, object value)
{
var otherEntry = StateManager.TryGetEntry(value, targetType, throwOnTypeMismatch: false);

builder.Append(
otherEntry == null
? "<not found>"
: otherEntry.BuildCurrentValuesString(targetType.FindPrimaryKey().Properties));
}
}

IUpdateEntry IUpdateEntry.SharedIdentityEntry => SharedIdentityEntry;

Expand Down
11 changes: 11 additions & 0 deletions src/EFCore/ChangeTracking/Internal/StateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,5 +1254,16 @@ public virtual void OnStateChanged(InternalEntityEntry internalEntityEntry, Enti

@event?.Invoke(Context.ChangeTracker, new EntityStateChangedEventArgs(internalEntityEntry, oldState, newState));
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual DebugView DebugView
=> new DebugView(
() => this.ToDebugString(StateManagerDebugStringOptions.ShortDefault),
() => this.ToDebugString(StateManagerDebugStringOptions.LongDefault));
}
}
Loading

0 comments on commit af8ff54

Please sign in to comment.