-
Notifications
You must be signed in to change notification settings - Fork 351
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
allow configuring alternate key vocabulary and address performance co… #2491
base: release-7.x
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2155,14 +2155,37 @@ public static bool IsKey(this IEdmProperty property) | |
/// <param name="type">Reference to the calling object.</param> | ||
/// <returns>Alternate Keys of this type.</returns> | ||
public static IEnumerable<IDictionary<string, IEdmProperty>> GetAlternateKeysAnnotation(this IEdmModel model, IEdmEntityType type) | ||
{ | ||
return GetAlternateKeysAnnotation(model, type, new[] { AlternateKeysVocabularyModel.AlternateKeysTerm, CoreVocabularyModel.AlternateKeysTerm }); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the declared alternate keys of the most defined entity with a declared key present. | ||
/// </summary> | ||
/// <param name="model">The model to be used.</param> | ||
/// <param name="type">Reference to the calling object.</param> | ||
/// <param name="alternateKeyTerms">The <see cref="IEdmTerm"/>s that are used within <paramref name="model"/> to represent alternate key annotations</param> | ||
/// <returns>Alternate Keys of this type.</returns> | ||
/// <exception cref="ArgumentNullException"> | ||
/// Thrown if <paramref name="model"/> or <paramref name="type"/> or <paramref name="alternateKeyTerms"/> is <see langword="null"/> | ||
/// </exception> | ||
/// <exception cref="ArgumentException">Thrown if <paramref name="alternateKeyTerms"/> contains any <see langword="null"/> values</exception> | ||
public static IEnumerable<IDictionary<string, IEdmProperty>> GetAlternateKeysAnnotation( | ||
this IEdmModel model, | ||
IEdmEntityType type, | ||
IEnumerable<IEdmTerm> alternateKeyTerms) | ||
{ | ||
EdmUtil.CheckArgumentNull(model, "model"); | ||
EdmUtil.CheckArgumentNull(type, "type"); | ||
EdmUtil.CheckArgumentNull(alternateKeyTerms, nameof(alternateKeyTerms)); | ||
|
||
IEdmEntityType checkingType = type; | ||
while (checkingType != null) | ||
{ | ||
IEnumerable<IDictionary<string, IEdmProperty>> declaredAlternateKeys = GetDeclaredAlternateKeysForType(checkingType, model); | ||
IEnumerable<IDictionary<string, IEdmProperty>> declaredAlternateKeys = GetDeclaredAlternateKeysForType( | ||
checkingType, | ||
model, | ||
alternateKeyTerms); | ||
if (declaredAlternateKeys != null) | ||
{ | ||
return declaredAlternateKeys; | ||
|
@@ -3462,24 +3485,31 @@ internal static bool HasAny<T>(this IEnumerable<T> enumerable) where T : class | |
/// </summary> | ||
/// <param name="type">Reference to the calling object.</param> | ||
/// <param name="model">The model to be used.</param> | ||
/// <param name="alternateKeyTerms"> | ||
/// The <see cref="IEdmTerm"/>s that are used within <paramref name="model"/> to represent alternate key annotations; assumed to not be <see langword="null"/> | ||
/// </param> | ||
/// <returns>Alternate Keys of this type.</returns> | ||
private static IEnumerable<IDictionary<string, IEdmProperty>> GetDeclaredAlternateKeysForType(IEdmEntityType type, IEdmModel model) | ||
/// <exception cref="ArgumentException">Thrown if <paramref name="alternateKeyTerms"/> contains any <see langword="null"/> values</exception> | ||
private static IEnumerable<IDictionary<string, IEdmProperty>> GetDeclaredAlternateKeysForType( | ||
IEdmEntityType type, | ||
IEdmModel model, | ||
IEnumerable<IEdmTerm> alternateKeyTerms) | ||
{ | ||
IEdmVocabularyAnnotation annotationValue = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(type, AlternateKeysVocabularyModel.AlternateKeysTerm).FirstOrDefault(); | ||
IEdmVocabularyAnnotation coreAnnotationValue = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(type, CoreVocabularyModel.AlternateKeysTerm).FirstOrDefault(); | ||
|
||
if (annotationValue != null || coreAnnotationValue != null) | ||
var any = false; | ||
var declaredAlternateKeys = new List<IDictionary<string, IEdmProperty>>(); | ||
foreach (var alternateKeyTerm in alternateKeyTerms) | ||
{ | ||
List<IDictionary<string, IEdmProperty>> declaredAlternateKeys = new List<IDictionary<string, IEdmProperty>>(); | ||
if (alternateKeyTerm == null) | ||
{ | ||
throw new ArgumentException(Strings.NullTermForAlternateKey(nameof(alternateKeyTerms))); | ||
} | ||
|
||
Action<IEdmVocabularyAnnotation> retrieveAnnotationAction = ann => | ||
var annotationValue = model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(type, alternateKeyTerm).FirstOrDefault(); | ||
if (annotationValue != null) | ||
{ | ||
if (ann == null) | ||
{ | ||
return; | ||
} | ||
any = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we wait to set this until we have a value on line 3539 (i.e., versus the collectionexpression being empty)? It looks like both the existing and new code could return either null or an empty dictionary, so the calling code presumably has to be prepared for either. Is there an advantage to returning one over the other? |
||
|
||
IEdmCollectionExpression keys = ann.Value as IEdmCollectionExpression; | ||
IEdmCollectionExpression keys = annotationValue.Value as IEdmCollectionExpression; | ||
Debug.Assert(keys != null, "expected IEdmCollectionExpression for alternate key annotation value"); | ||
|
||
foreach (IEdmRecordExpression key in keys.Elements.OfType<IEdmRecordExpression>()) | ||
|
@@ -3510,13 +3540,11 @@ private static IEnumerable<IDictionary<string, IEdmProperty>> GetDeclaredAlterna | |
} | ||
} | ||
} | ||
}; | ||
|
||
// For backwards-compability, we merge the alternate keys from community and core vocabulary annotations. | ||
|
||
retrieveAnnotationAction(annotationValue); | ||
retrieveAnnotationAction(coreAnnotationValue); | ||
} | ||
} | ||
|
||
if (any) | ||
{ | ||
return declaredAlternateKeys; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have traditionally avoided use of "var" in production code (we do use it in test code).