Skip to content

Commit

Permalink
Add ConventionalAnnotation to store ConfigurationSource in instead of…
Browse files Browse the repository at this point in the history
… InternalMetadataBuilder

Part of #3476
  • Loading branch information
AndriySvyryd committed Oct 30, 2015
1 parent c4d56ff commit 7e45551
Show file tree
Hide file tree
Showing 43 changed files with 671 additions and 657 deletions.
1 change: 1 addition & 0 deletions EntityFramework.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue">True</s:Boolean>

<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/JavaScriptFormatOther/ALIGN_MULTIPLE_DECLARATION/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/XmlDocFormatter/WrapLimit/@EntryValue">140</s:Int64>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/XmlFormatter/WrapBeforeAttr/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/XmlFormatter/WrapInsideText/@EntryValue">True</s:Boolean>

Expand Down
6 changes: 4 additions & 2 deletions src/EntityFramework.Core/EntityFramework.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;CSPROJ</DefineConstants>
<DefineConstants>TRACE;CSPROJ;NET451</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand Down Expand Up @@ -86,6 +86,8 @@
<Compile Include="Internal\IDatabaseProviderSelector.cs" />
<Compile Include="Internal\IndentedStringBuilder.cs" />
<Compile Include="Internal\LazyRef.cs" />
<Compile Include="Metadata\Internal\ConventionalAnnotatable.cs" />
<Compile Include="Metadata\Internal\ConventionalAnnotation.cs" />
<Compile Include="Metadata\Internal\ICanGetNavigations.cs" />
<Compile Include="Metadata\Internal\INavigationAccessors.cs" />
<Compile Include="Metadata\Internal\IPropertyBaseAccessors.cs" />
Expand Down Expand Up @@ -492,4 +494,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
139 changes: 77 additions & 62 deletions src/EntityFramework.Core/Infrastructure/Annotatable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,143 +3,158 @@

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Data.Entity.Internal;
using Microsoft.Data.Entity.Metadata;
using Microsoft.Data.Entity.Utilities;

namespace Microsoft.Data.Entity.Infrastructure
{
/// <summary>
/// <para>
/// Base class for types that support reading and writing annotations.
/// Base class for types that support reading and writing annotations.
/// </para>
/// <para>
/// This type is typically used by database providers (and other extensions). It is generally
/// not used in application code.
/// </para>
/// </summary>
public class Annotatable : IAnnotatable
public class Annotatable : IMutableAnnotatable
{
// TODO: Perf: use a mutable structure before the model is made readonly
// Issue #868
private readonly LazyRef<ImmutableSortedSet<Annotation>> _annotations
= new LazyRef<ImmutableSortedSet<Annotation>>(
() => ImmutableSortedSet<Annotation>.Empty.WithComparer(new AnnotationComparer()));
private readonly LazyRef<SortedDictionary<string, Annotation>> _annotations =
new LazyRef<SortedDictionary<string, Annotation>>(() => new SortedDictionary<string, Annotation>());

/// <summary>
/// Gets all annotations on the current object.
/// </summary>
public virtual IEnumerable<Annotation> GetAnnotations() =>
_annotations.HasValue
? _annotations.Value.Values
: Enumerable.Empty<Annotation>();

/// <summary>
/// Adds an annotation to this object. Throws if an annotation with the specified name already exists.
/// </summary>
/// <param name="annotationName"> The key of the annotation to be added. </param>
/// <param name="name"> The key of the annotation to be added. </param>
/// <param name="value"> The value to be stored in the annotation. </param>
/// <returns> The newly added annotation. </returns>
public virtual Annotation AddAnnotation([NotNull] string annotationName, [NotNull] object value)
public virtual Annotation AddAnnotation(string name, object value)
{
Check.NotEmpty(annotationName, nameof(annotationName));
Check.NotEmpty(name, nameof(name));
Check.NotNull(value, nameof(value));

var annotation = new Annotation(annotationName, value);
var annotation = CreateAnnotation(name, value);

return AddAnnotation(name, annotation);
}

protected virtual Annotation AddAnnotation([NotNull] string name, [NotNull] Annotation annotation)
{
var previousLength = _annotations.Value.Count;
_annotations.Value = _annotations.Value.Add(annotation);
SetAnnotation(name, annotation);

if (previousLength == _annotations.Value.Count)
{
throw new InvalidOperationException(CoreStrings.DuplicateAnnotation(annotationName));
throw new InvalidOperationException(CoreStrings.DuplicateAnnotation(name));
}

return annotation;
}

protected virtual Annotation SetAnnotation([NotNull] string name, [NotNull] Annotation annotation)
{
_annotations.Value[name] = annotation;

return annotation;
}

/// <summary>
/// Adds an annotation to this object or returns the existing annotation if one with the specified name already exists.
/// Adds an annotation to this object or returns the existing annotation if one with the specified name
/// already exists.
/// </summary>
/// <param name="annotationName"> The key of the annotation to be added. </param>
/// <param name="name"> The key of the annotation to be added. </param>
/// <param name="value"> The value to be stored in the annotation. </param>
/// <returns>
/// The existing annotation if an annotation with the specified name already exists. Otherwise, the newly added annotation.
/// <returns>
/// The existing annotation if an annotation with the specified name already exists. Otherwise, the newly
/// added annotation.
/// </returns>
public virtual Annotation GetOrAddAnnotation([NotNull] string annotationName, [NotNull] object value)
=> FindAnnotation(annotationName) ?? AddAnnotation(annotationName, value);
public virtual Annotation GetOrAddAnnotation([NotNull] string name, [NotNull] object value)
=> FindAnnotation(name) ?? AddAnnotation(name, value);

/// <summary>
/// Gets the annotation with the given name, returning null if it does not exist.
/// </summary>
/// <param name="annotationName"> The key of the annotation to find. </param>
/// <param name="name"> The key of the annotation to find. </param>
/// <returns>
/// The existing annotation if an annotation with the specified name already exists. Otherwise, null.
/// The existing annotation if an annotation with the specified name already exists. Otherwise, null.
/// </returns>
public virtual Annotation FindAnnotation([NotNull] string annotationName)
public virtual Annotation FindAnnotation(string name)
{
Check.NotEmpty(annotationName, nameof(annotationName));
Check.NotEmpty(name, nameof(name));

if (!_annotations.HasValue)
{
return null;
}

Annotation annotation;
return _annotations.HasValue
&& _annotations.Value.TryGetValue(new Annotation(annotationName, "_"), out annotation)
return _annotations.Value.TryGetValue(name, out annotation)
? annotation
: null;
}

/// <summary>
/// Removes the given annotation from this object.
/// </summary>
/// <param name="annotationName"> The annotation to remove. </param>
/// <param name="name"> The annotation to remove. </param>
/// <returns> The annotation that was removed. </returns>
public virtual Annotation RemoveAnnotation([NotNull] string annotationName)
public virtual Annotation RemoveAnnotation(string name)
{
Check.NotNull(annotationName, nameof(annotationName));

var previousAnnotations = _annotations.Value;
var annotation = new Annotation(annotationName, "_");
_annotations.Value = _annotations.Value.Remove(annotation);
Check.NotNull(name, nameof(name));

Annotation removedAnnotations = null;
if (previousAnnotations.Count != _annotations.Value.Count)
var annotation = FindAnnotation(name);
if (annotation == null)
{
previousAnnotations.TryGetValue(annotation, out removedAnnotations);
return null;
}

return removedAnnotations;
_annotations.Value.Remove(name);

return annotation;
}

/// <summary>
/// Gets the value annotation with the given name, returning null if it does not exist.
/// </summary>
/// <param name="annotationName"> The key of the annotation to find. </param>
/// <returns>
/// The value of the existing annotation if an annotation with the specified name already exists. Otherwise, null.
/// <param name="name"> The key of the annotation to find. </param>
/// <returns>
/// The value of the existing annotation if an annotation with the specified name already exists.
/// Otherwise, null.
/// </returns>
// ReSharper disable once AnnotationRedundancyInHierarchy
// TODO: Fix API test to handle indexer
public virtual object this[[NotNull] string annotationName]
public virtual object this[[NotNull] string name]
{
get { return FindAnnotation(annotationName)?.Value; }
get { return FindAnnotation(name)?.Value; }
[param: CanBeNull]
set
{
Check.NotEmpty(annotationName, nameof(annotationName));

_annotations.Value = _annotations.Value.Remove(new Annotation(annotationName, "_"));
Check.NotEmpty(name, nameof(name));

if (value != null)
if (value == null)
{
RemoveAnnotation(name);
}
else
{
AddAnnotation(annotationName, value);
_annotations.Value[name] = CreateAnnotation(name, value);
}
}
}

/// <summary>
/// Gets all annotations on the current object.
/// </summary>
public virtual IEnumerable<Annotation> GetAnnotations()
=> _annotations.HasValue
? (IEnumerable<Annotation>)_annotations.Value
: ImmutableList<Annotation>.Empty;

private class AnnotationComparer : IComparer<IAnnotation>
{
public int Compare(IAnnotation x, IAnnotation y) => StringComparer.Ordinal.Compare(x.Name, y.Name);
}
protected virtual Annotation CreateAnnotation([NotNull] string name, [NotNull] object value)
=> new Annotation(name, value);

/// <summary>
/// Gets all annotations on the current object.
Expand All @@ -149,10 +164,10 @@ private class AnnotationComparer : IComparer<IAnnotation>
/// <summary>
/// Gets the annotation with the given name, returning null if it does not exist.
/// </summary>
/// <param name="annotationName"> The key of the annotation to find. </param>
/// <param name="name"> The key of the annotation to find. </param>
/// <returns>
/// The existing annotation if an annotation with the specified name already exists. Otherwise, null.
/// The existing annotation if an annotation with the specified name already exists. Otherwise, null.
/// </returns>
IAnnotation IAnnotatable.FindAnnotation(string annotationName) => FindAnnotation(annotationName);
IAnnotation IAnnotatable.FindAnnotation(string name) => FindAnnotation(name);
}
}
8 changes: 4 additions & 4 deletions src/EntityFramework.Core/Infrastructure/IAnnotatable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ public interface IAnnotatable
/// <summary>
/// Gets the value annotation with the given name, returning null if it does not exist.
/// </summary>
/// <param name="annotationName"> The key of the annotation to find. </param>
/// <param name="name"> The key of the annotation to find. </param>
/// <returns>
/// The value of the existing annotation if an annotation with the specified name already exists. Otherwise, null.
/// </returns>
// ReSharper disable once AnnotationRedundancyInHierarchy
// TODO: Fix API test to handle indexer
object this[[NotNull] string annotationName] { get; }
object this[[NotNull] string name] { get; }

/// <summary>
/// Gets the annotation with the given name, returning null if it does not exist.
/// </summary>
/// <param name="annotationName"> The key of the annotation to find. </param>
/// <param name="name"> The key of the annotation to find. </param>
/// <returns>
/// The existing annotation if an annotation with the specified name already exists. Otherwise, null.
/// </returns>
IAnnotation FindAnnotation([NotNull] string annotationName);
IAnnotation FindAnnotation([NotNull] string name);

/// <summary>
/// Gets all annotations on the current object.
Expand Down
6 changes: 3 additions & 3 deletions src/EntityFramework.Core/Infrastructure/ModelSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ protected virtual IModel CreateModel(
Check.NotNull(validator, nameof(validator));

var conventionSet = CreateConventionSet(conventionSetBuilder);
var model = new Model();

model.SetProductVersion(ProductInfo.GetVersion());
var modelBuilder = new ModelBuilder(conventionSet);

var modelBuilder = new ModelBuilder(conventionSet, model);
var model = (Model)modelBuilder.Model;
model.SetProductVersion(ProductInfo.GetVersion());

FindSets(modelBuilder, context);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityT
var directlyDerivedTypes = entityType.Model.GetEntityTypes().Where(t =>
t.BaseType == entityType.BaseType
&& t.HasClrType()
&& FindClosestBaseType(t) == entityType);
&& FindClosestBaseType(t) == entityType)
.ToList();

foreach (var directlyDerivedType in directlyDerivedTypes)
{
Expand Down
19 changes: 11 additions & 8 deletions src/EntityFramework.Core/Metadata/IMutableAnnotatable.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using JetBrains.Annotations;
using Microsoft.Data.Entity.Infrastructure;
Expand All @@ -19,13 +22,13 @@ public interface IMutableAnnotatable : IAnnotatable
/// <summary>
/// Gets or sets the value of the annotation with the given name.
/// </summary>
/// <param name="annotationName"> The key of the annotation. </param>
/// <param name="name"> The key of the annotation. </param>
/// <returns>
/// The value of the existing annotation if an annotation with the specified name already exists. Otherwise, null.
/// </returns>
// ReSharper disable once AnnotationRedundancyInHierarchy
// TODO: Fix API test to handle indexer
new object this[[NotNull] string annotationName] { get; [param: CanBeNull] set; }
new object this[[NotNull] string name] { get; [param: CanBeNull] set; }

/// <summary>
/// Gets all annotations on the current object.
Expand All @@ -35,25 +38,25 @@ public interface IMutableAnnotatable : IAnnotatable
/// <summary>
/// Adds an annotation to this object. Throws if an annotation with the specified name already exists.
/// </summary>
/// <param name="annotationName"> The key of the annotation to be added. </param>
/// <param name="name"> The key of the annotation to be added. </param>
/// <param name="value"> The value to be stored in the annotation. </param>
/// <returns> The newly added annotation. </returns>
Annotation AddAnnotation([NotNull] string annotationName, [NotNull] object value);
Annotation AddAnnotation([NotNull] string name, [NotNull] object value);

/// <summary>
/// Gets the annotation with the given name, returning null if it does not exist.
/// </summary>
/// <param name="annotationName"> The key of the annotation to find. </param>
/// <param name="name"> The key of the annotation to find. </param>
/// <returns>
/// The existing annotation if an annotation with the specified name already exists. Otherwise, null.
/// </returns>
new Annotation FindAnnotation([NotNull] string annotationName);
new Annotation FindAnnotation([NotNull] string name);

/// <summary>
/// Removes the given annotation from this object.
/// </summary>
/// <param name="annotationName"> The annotation to remove. </param>
/// <param name="name"> The annotation to remove. </param>
/// <returns> The annotation that was removed. </returns>
Annotation RemoveAnnotation([NotNull] string annotationName);
Annotation RemoveAnnotation([NotNull] string name);
}
}
5 changes: 4 additions & 1 deletion src/EntityFramework.Core/Metadata/IMutableForeignKey.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using JetBrains.Annotations;

Expand Down Expand Up @@ -86,4 +89,4 @@ public interface IMutableForeignKey : IForeignKey, IMutableAnnotatable
/// </summary>
new DeleteBehavior? DeleteBehavior { get; set; }
}
}
}
2 changes: 1 addition & 1 deletion src/EntityFramework.Core/Metadata/IMutableModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ public interface IMutableModel : IModel, IMutableAnnotatable
/// Gets all entities types defined in the model.
/// </summary>
/// <returns> All entities types defined in the model. </returns>
new IReadOnlyList<IMutableEntityType> GetEntityTypes();
new IEnumerable<IMutableEntityType> GetEntityTypes();
}
}
Loading

0 comments on commit 7e45551

Please sign in to comment.