Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ConventionalAnnotation to store ConfigurationSource in instead of InternalMetadataBuilder #3607

Merged
merged 1 commit into from
Oct 30, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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