Code cleanup
This commit is contained in:
Родитель
e88fa4a92c
Коммит
3c20186392
|
@ -46,7 +46,8 @@ public sealed class StringDictionaryComparer<TDictionary, TElement> : ValueCompa
|
|||
/// </summary>
|
||||
public ValueComparer ElementComparer { get; }
|
||||
|
||||
ValueComparer IInfrastructure<ValueComparer>.Instance => ElementComparer;
|
||||
ValueComparer IInfrastructure<ValueComparer>.Instance
|
||||
=> ElementComparer;
|
||||
|
||||
private static Expression<Func<object?, object?, bool>> CompareLambda(ValueComparer elementComparer)
|
||||
{
|
||||
|
|
|
@ -41,7 +41,6 @@ public static class CosmosEventId
|
|||
|
||||
// Model validation events
|
||||
NoPartitionKeyDefined = CoreEventId.ProviderBaseId + 600,
|
||||
|
||||
}
|
||||
|
||||
private static readonly string DatabasePrefix = DbLoggerCategory.Database.Name + ".";
|
||||
|
|
|
@ -508,7 +508,8 @@ public static class CosmosLoggerExtensions
|
|||
{
|
||||
var eventData = new PropertyEventData(
|
||||
definition,
|
||||
(d, p) => ((EventDefinition<string, string>)d).GenerateMessage(((PropertyEventData)p).Property.DeclaringType.DisplayName(), ((PropertyEventData)p).Property.Name),
|
||||
(d, p) => ((EventDefinition<string, string>)d).GenerateMessage(
|
||||
((PropertyEventData)p).Property.DeclaringType.DisplayName(), ((PropertyEventData)p).Property.Name),
|
||||
property);
|
||||
diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,10 @@ public static class CosmosDbFunctionsExtensions
|
|||
/// <paramref name="expression2" /> will be returned.
|
||||
/// </param>
|
||||
/// <param name="expression2">The expression to be returned if <paramref name="expression1" /> is <c>undefined</c>.</param>
|
||||
/// <seealso href="https://learn.microsoft.com/azure/cosmos-db/nosql/query/ternary-coalesce-operators#coalesce-operator">Cosmos coalesce operator</seealso>
|
||||
/// <seealso href="https://learn.microsoft.com/azure/cosmos-db/nosql/query/ternary-coalesce-operators#coalesce-operator">
|
||||
/// Cosmos coalesce
|
||||
/// operator
|
||||
/// </seealso>
|
||||
public static T CoalesceUndefined<T>(
|
||||
this DbFunctions _,
|
||||
T expression1,
|
||||
|
@ -52,7 +55,9 @@ public static class CosmosDbFunctionsExtensions
|
|||
|
||||
/// <summary>
|
||||
/// Returns the distance between two vectors, using the distance function and data type defined using
|
||||
/// <see cref="CosmosPropertyBuilderExtensions.IsVector(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder,Microsoft.Azure.Cosmos.DistanceFunction,int)"/>.
|
||||
/// <see
|
||||
/// cref="CosmosPropertyBuilderExtensions.IsVector(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder,Microsoft.Azure.Cosmos.DistanceFunction,int)" />
|
||||
/// .
|
||||
/// </summary>
|
||||
/// <param name="_">The <see cref="DbFunctions" /> instance.</param>
|
||||
/// <param name="vector1">The first vector.</param>
|
||||
|
@ -67,9 +72,11 @@ public static class CosmosDbFunctionsExtensions
|
|||
/// <param name="_">The <see cref="DbFunctions" /> instance.</param>
|
||||
/// <param name="vector1">The first vector.</param>
|
||||
/// <param name="vector2">The second vector.</param>
|
||||
/// <param name="useBruteForce">A <see langword="bool"/> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true"/>, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.</param>
|
||||
/// <param name="useBruteForce">
|
||||
/// A <see langword="bool" /> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true" />, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.
|
||||
/// </param>
|
||||
[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)]
|
||||
public static double VectorDistance(
|
||||
this DbFunctions _,
|
||||
|
@ -85,9 +92,11 @@ public static class CosmosDbFunctionsExtensions
|
|||
/// <param name="vector1">The first vector.</param>
|
||||
/// <param name="vector2">The second vector.</param>
|
||||
/// <param name="distanceFunction">The distance function to use.</param>
|
||||
/// <param name="useBruteForce">A <see langword="bool"/> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true"/>, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.</param>
|
||||
/// <param name="useBruteForce">
|
||||
/// A <see langword="bool" /> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true" />, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.
|
||||
/// </param>
|
||||
[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)]
|
||||
public static double VectorDistance(
|
||||
this DbFunctions _,
|
||||
|
@ -99,7 +108,9 @@ public static class CosmosDbFunctionsExtensions
|
|||
|
||||
/// <summary>
|
||||
/// Returns the distance between two vectors, using the distance function and data type defined using
|
||||
/// <see cref="CosmosPropertyBuilderExtensions.IsVector(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder,Microsoft.Azure.Cosmos.DistanceFunction,int)"/>.
|
||||
/// <see
|
||||
/// cref="CosmosPropertyBuilderExtensions.IsVector(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder,Microsoft.Azure.Cosmos.DistanceFunction,int)" />
|
||||
/// .
|
||||
/// </summary>
|
||||
/// <param name="_">The <see cref="DbFunctions" /> instance.</param>
|
||||
/// <param name="vector1">The first vector.</param>
|
||||
|
@ -114,9 +125,11 @@ public static class CosmosDbFunctionsExtensions
|
|||
/// <param name="_">The <see cref="DbFunctions" /> instance.</param>
|
||||
/// <param name="vector1">The first vector.</param>
|
||||
/// <param name="vector2">The second vector.</param>
|
||||
/// <param name="useBruteForce">A <see langword="bool"/> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true"/>, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.</param>
|
||||
/// <param name="useBruteForce">
|
||||
/// A <see langword="bool" /> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true" />, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.
|
||||
/// </param>
|
||||
[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)]
|
||||
public static double VectorDistance(
|
||||
this DbFunctions _,
|
||||
|
@ -132,9 +145,11 @@ public static class CosmosDbFunctionsExtensions
|
|||
/// <param name="vector1">The first vector.</param>
|
||||
/// <param name="vector2">The second vector.</param>
|
||||
/// <param name="distanceFunction">The distance function to use.</param>
|
||||
/// <param name="useBruteForce">A <see langword="bool"/> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true"/>, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.</param>
|
||||
/// <param name="useBruteForce">
|
||||
/// A <see langword="bool" /> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true" />, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.
|
||||
/// </param>
|
||||
[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)]
|
||||
public static double VectorDistance(
|
||||
this DbFunctions _,
|
||||
|
@ -146,7 +161,9 @@ public static class CosmosDbFunctionsExtensions
|
|||
|
||||
/// <summary>
|
||||
/// Returns the distance between two vectors, using the distance function and data type defined using
|
||||
/// <see cref="CosmosPropertyBuilderExtensions.IsVector(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder,Microsoft.Azure.Cosmos.DistanceFunction,int)"/>.
|
||||
/// <see
|
||||
/// cref="CosmosPropertyBuilderExtensions.IsVector(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder,Microsoft.Azure.Cosmos.DistanceFunction,int)" />
|
||||
/// .
|
||||
/// </summary>
|
||||
/// <param name="_">The <see cref="DbFunctions" /> instance.</param>
|
||||
/// <param name="vector1">The first vector.</param>
|
||||
|
@ -161,9 +178,11 @@ public static class CosmosDbFunctionsExtensions
|
|||
/// <param name="_">The <see cref="DbFunctions" /> instance.</param>
|
||||
/// <param name="vector1">The first vector.</param>
|
||||
/// <param name="vector2">The second vector.</param>
|
||||
/// <param name="useBruteForce">A <see langword="bool"/> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true"/>, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.</param>
|
||||
/// <param name="useBruteForce">
|
||||
/// A <see langword="bool" /> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true" />, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.
|
||||
/// </param>
|
||||
[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)]
|
||||
public static double VectorDistance(
|
||||
this DbFunctions _,
|
||||
|
@ -179,9 +198,11 @@ public static class CosmosDbFunctionsExtensions
|
|||
/// <param name="vector1">The first vector.</param>
|
||||
/// <param name="vector2">The second vector.</param>
|
||||
/// <param name="distanceFunction">The distance function to use.</param>
|
||||
/// <param name="useBruteForce">A <see langword="bool"/> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true"/>, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.</param>
|
||||
/// <param name="useBruteForce">
|
||||
/// A <see langword="bool" /> specifying how the computed value is used in an ORDER BY
|
||||
/// expression. If <see langword="true" />, then brute force is used, otherwise any index defined on the vector
|
||||
/// property is leveraged.
|
||||
/// </param>
|
||||
[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)]
|
||||
public static double VectorDistance(
|
||||
this DbFunctions _,
|
||||
|
|
|
@ -559,7 +559,8 @@ public static class CosmosEntityTypeBuilderExtensions
|
|||
/// </param>
|
||||
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
|
||||
public static EntityTypeBuilder<TEntity> HasDiscriminatorInJsonId<TEntity>(
|
||||
this EntityTypeBuilder<TEntity> entityTypeBuilder, bool? includeDiscriminator = true)
|
||||
this EntityTypeBuilder<TEntity> entityTypeBuilder,
|
||||
bool? includeDiscriminator = true)
|
||||
where TEntity : class
|
||||
=> (EntityTypeBuilder<TEntity>)HasDiscriminatorInJsonId((EntityTypeBuilder)entityTypeBuilder, includeDiscriminator);
|
||||
|
||||
|
@ -578,7 +579,8 @@ public static class CosmosEntityTypeBuilderExtensions
|
|||
/// </param>
|
||||
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
|
||||
public static EntityTypeBuilder<TEntity> IncludeRootDiscriminatorInJsonId<TEntity>(
|
||||
this EntityTypeBuilder<TEntity> entityTypeBuilder, bool? includeDiscriminator = true)
|
||||
this EntityTypeBuilder<TEntity> entityTypeBuilder,
|
||||
bool? includeDiscriminator = true)
|
||||
where TEntity : class
|
||||
=> (EntityTypeBuilder<TEntity>)IncludeRootDiscriminatorInJsonId((EntityTypeBuilder)entityTypeBuilder, includeDiscriminator);
|
||||
|
||||
|
@ -597,7 +599,9 @@ public static class CosmosEntityTypeBuilderExtensions
|
|||
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
|
||||
/// <returns>The same builder instance if the configuration was applied, <see langword="null" /> otherwise.</returns>
|
||||
public static IConventionEntityTypeBuilder? HasDiscriminatorInJsonId(
|
||||
this IConventionEntityTypeBuilder entityTypeBuilder, bool? includeDiscriminator, bool fromDataAnnotation = false)
|
||||
this IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
bool? includeDiscriminator,
|
||||
bool fromDataAnnotation = false)
|
||||
{
|
||||
if (!entityTypeBuilder.CanSetDiscriminatorInJsonId(includeDiscriminator, fromDataAnnotation))
|
||||
{
|
||||
|
@ -630,7 +634,9 @@ public static class CosmosEntityTypeBuilderExtensions
|
|||
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
|
||||
/// <returns>The same builder instance if the configuration was applied, <see langword="null" /> otherwise.</returns>
|
||||
public static IConventionEntityTypeBuilder? IncludeRootDiscriminatorInJsonId(
|
||||
this IConventionEntityTypeBuilder entityTypeBuilder, bool? includeDiscriminator, bool fromDataAnnotation = false)
|
||||
this IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
bool? includeDiscriminator,
|
||||
bool fromDataAnnotation = false)
|
||||
{
|
||||
if (!entityTypeBuilder.CanSetIncludeRootDiscriminatorInJsonId(includeDiscriminator, fromDataAnnotation))
|
||||
{
|
||||
|
@ -678,7 +684,6 @@ public static class CosmosEntityTypeBuilderExtensions
|
|||
: IdDiscriminatorMode.None, fromDataAnnotation);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the setting for including the discriminator can be set
|
||||
/// from the current configuration source
|
||||
|
|
|
@ -194,7 +194,7 @@ public static class CosmosEntityTypeExtensions
|
|||
/// Returns the names of the properties that are used to store the hierarchical partition key, if any.
|
||||
/// </summary>
|
||||
/// <param name="entityType">The entity type.</param>
|
||||
/// <returns>The names of the partition key properties, or <see langword="null"/> if not set.</returns>
|
||||
/// <returns>The names of the partition key properties, or <see langword="null" /> if not set.</returns>
|
||||
public static IReadOnlyList<string> GetPartitionKeyPropertyNames(this IReadOnlyEntityType entityType)
|
||||
=> entityType[CosmosAnnotationNames.PartitionKeyNames] as IReadOnlyList<string>
|
||||
?? entityType.BaseType?.GetPartitionKeyPropertyNames()
|
||||
|
@ -204,7 +204,7 @@ public static class CosmosEntityTypeExtensions
|
|||
/// Sets the names of the properties that are used to store the hierarchical partition key.
|
||||
/// </summary>
|
||||
/// <param name="entityType">The entity type.</param>
|
||||
/// <param name="names">The names to set, or <see langword="null"/> to clear all names.</param>
|
||||
/// <param name="names">The names to set, or <see langword="null" /> to clear all names.</param>
|
||||
public static void SetPartitionKeyPropertyNames(this IMutableEntityType entityType, IReadOnlyList<string>? names)
|
||||
=> entityType.SetOrRemoveAnnotation(
|
||||
CosmosAnnotationNames.PartitionKeyNames, names is null ? names : Check.HasNoEmptyElements(names, nameof(names)));
|
||||
|
@ -352,7 +352,8 @@ public static class CosmosEntityTypeExtensions
|
|||
/// <returns>
|
||||
/// <see langword="true" /> to force __id creation, <see langword="false" /> to not force __id creation,
|
||||
/// <see langword="null" /> to revert to the default setting.
|
||||
/// .</returns>
|
||||
/// .
|
||||
/// </returns>
|
||||
public static bool? GetHasShadowId(this IReadOnlyEntityType entityType)
|
||||
=> (entityType.BaseType != null
|
||||
? entityType.GetRootType().GetHasShadowId()
|
||||
|
@ -389,7 +390,7 @@ public static class CosmosEntityTypeExtensions
|
|||
CosmosAnnotationNames.HasShadowId, alwaysCreate, fromDataAnnotation)?.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ConfigurationSource" /> for <see cref="GetHasShadowId"/>.
|
||||
/// Gets the <see cref="ConfigurationSource" /> for <see cref="GetHasShadowId" />.
|
||||
/// </summary>
|
||||
/// <param name="entityType">The entity typer.</param>
|
||||
/// <returns>The <see cref="ConfigurationSource" />.</returns>
|
||||
|
@ -401,7 +402,7 @@ public static class CosmosEntityTypeExtensions
|
|||
/// Prior to EF Core 9, it was always included. Starting with EF Core 9, it is not included by default.
|
||||
/// </summary>
|
||||
/// <param name="entityType">The entity type.</param>
|
||||
/// <returns>The <see cref="IdDiscriminatorMode"/> or <see langword="null" /> if not set.</returns>
|
||||
/// <returns>The <see cref="IdDiscriminatorMode" /> or <see langword="null" /> if not set.</returns>
|
||||
public static IdDiscriminatorMode? GetDiscriminatorInKey(this IReadOnlyEntityType entityType)
|
||||
=> (entityType.BaseType != null
|
||||
? entityType.GetRootType().GetDiscriminatorInKey()
|
||||
|
@ -423,12 +424,14 @@ public static class CosmosEntityTypeExtensions
|
|||
/// <param name="behavior">The behavior to use, or <see langword="null" /> to reset the behavior to the default.</param>
|
||||
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
|
||||
public static IdDiscriminatorMode? SetDiscriminatorInKey(
|
||||
this IConventionEntityType entityType, IdDiscriminatorMode? behavior, bool fromDataAnnotation = false)
|
||||
this IConventionEntityType entityType,
|
||||
IdDiscriminatorMode? behavior,
|
||||
bool fromDataAnnotation = false)
|
||||
=> (IdDiscriminatorMode?)entityType.SetOrRemoveAnnotation(
|
||||
CosmosAnnotationNames.DiscriminatorInKey, behavior, fromDataAnnotation)?.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ConfigurationSource" /> for <see cref="GetDiscriminatorInKey"/>.
|
||||
/// Gets the <see cref="ConfigurationSource" /> for <see cref="GetDiscriminatorInKey" />.
|
||||
/// </summary>
|
||||
/// <param name="entityType">The entity typer.</param>
|
||||
/// <returns>The <see cref="ConfigurationSource" />.</returns>
|
||||
|
|
|
@ -8,7 +8,7 @@ using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
|
|||
namespace Microsoft.EntityFrameworkCore;
|
||||
|
||||
/// <summary>
|
||||
/// Azure Cosmos DB-specific extension methods for <see cref="IndexBuilder"/>.
|
||||
/// Azure Cosmos DB-specific extension methods for <see cref="IndexBuilder" />.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See <see href="https://aka.ms/efcore-docs-modeling">Modeling entity types and relationships</see>, and
|
||||
|
|
|
@ -55,7 +55,7 @@ public static class CosmosIndexExtensions
|
|||
fromDataAnnotation)?.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="ConfigurationSource" /> for whether the <see cref="GetVectorIndexType"/>.
|
||||
/// Returns the <see cref="ConfigurationSource" /> for whether the <see cref="GetVectorIndexType" />.
|
||||
/// </summary>
|
||||
/// <param name="property">The property.</param>
|
||||
/// <returns>The <see cref="ConfigurationSource" /> for whether the index is clustered.</returns>
|
||||
|
|
|
@ -96,7 +96,7 @@ public static class CosmosModelExtensions
|
|||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ConfigurationSource" />
|
||||
/// for <see cref="GetHasShadowIds"/>.
|
||||
/// for <see cref="GetHasShadowIds" />.
|
||||
/// </summary>
|
||||
/// <param name="model">The model.</param>
|
||||
/// <returns>The <see cref="ConfigurationSource" />.</returns>
|
||||
|
@ -108,7 +108,7 @@ public static class CosmosModelExtensions
|
|||
/// Prior to EF Core 9, it was always included. Starting with EF Core 9, it is not included by default.
|
||||
/// </summary>
|
||||
/// <param name="model">The model.</param>
|
||||
/// <returns>The <see cref="IdDiscriminatorMode"/> or <see langword="null" /> if not set.</returns>
|
||||
/// <returns>The <see cref="IdDiscriminatorMode" /> or <see langword="null" /> if not set.</returns>
|
||||
public static IdDiscriminatorMode? GetDiscriminatorInKey(this IReadOnlyModel model)
|
||||
=> (IdDiscriminatorMode?)model[CosmosAnnotationNames.DiscriminatorInKey];
|
||||
|
||||
|
@ -135,7 +135,7 @@ public static class CosmosModelExtensions
|
|||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ConfigurationSource" />
|
||||
/// for <see cref="GetDiscriminatorInKey"/>.
|
||||
/// for <see cref="GetDiscriminatorInKey" />.
|
||||
/// </summary>
|
||||
/// <param name="model">The model.</param>
|
||||
/// <returns>The <see cref="ConfigurationSource" />.</returns>
|
||||
|
|
|
@ -109,7 +109,10 @@ public static class CosmosPropertyExtensions
|
|||
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
|
||||
/// <returns>The configured value.</returns>
|
||||
[Experimental(EFDiagnostics.CosmosVectorSearchExperimental)]
|
||||
public static CosmosVectorType? SetVectorType(this IConventionProperty property, CosmosVectorType? vectorType, bool fromDataAnnotation = false)
|
||||
public static CosmosVectorType? SetVectorType(
|
||||
this IConventionProperty property,
|
||||
CosmosVectorType? vectorType,
|
||||
bool fromDataAnnotation = false)
|
||||
=> (CosmosVectorType?)property.SetOrRemoveAnnotation(
|
||||
CosmosAnnotationNames.VectorType,
|
||||
vectorType,
|
||||
|
|
|
@ -180,7 +180,6 @@ public static class CosmosQueryableExtensions
|
|||
internal static readonly MethodInfo ToPageAsyncMethodInfo
|
||||
= typeof(CosmosQueryableExtensions).GetMethod(nameof(ToPageAsync))!;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Allows paginating through query results by repeatedly executing the same query, passing continuation tokens to retrieve
|
||||
/// successive pages of the result set, and specifying the maximum number of results per page.
|
||||
|
|
|
@ -13,6 +13,7 @@ internal class Embedding : IEquatable<Embedding>
|
|||
public VectorDataType DataType { get; set; }
|
||||
public int Dimensions { get; set; }
|
||||
public DistanceFunction DistanceFunction { get; set; }
|
||||
|
||||
public bool Equals(Embedding? that)
|
||||
=> Equals(Path, that?.Path) && Equals(DataType, that?.DataType) && Equals(Dimensions, that.Dimensions);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ using System.Globalization;
|
|||
using System.Net;
|
||||
using System.Text;
|
||||
using Azure.Core;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Internal;
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Infrastructure.Internal;
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ public class CosmosSingletonOptions : ICosmosSingletonOptions
|
|||
/// 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 bool? EnableContentResponseOnWrite { get; private set; }
|
||||
public virtual bool? EnableContentResponseOnWrite { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -30,13 +30,13 @@ public class CosmosDiscriminatorConvention :
|
|||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc />
|
||||
public virtual void ProcessEntityTypeAdded(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
IConventionContext<IConventionEntityTypeBuilder> context)
|
||||
=> ProcessEntityType(entityTypeBuilder);
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc />
|
||||
public virtual void ProcessForeignKeyOwnershipChanged(
|
||||
IConventionForeignKeyBuilder relationshipBuilder,
|
||||
IConventionContext<bool?> context)
|
||||
|
@ -46,7 +46,7 @@ public class CosmosDiscriminatorConvention :
|
|||
ProcessEntityType(entityType.Builder);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc />
|
||||
public virtual void ProcessForeignKeyRemoved(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
IConventionForeignKey foreignKey,
|
||||
|
@ -59,7 +59,7 @@ public class CosmosDiscriminatorConvention :
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc />
|
||||
public virtual void ProcessEntityTypeAnnotationChanged(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
string name,
|
||||
|
@ -95,7 +95,7 @@ public class CosmosDiscriminatorConvention :
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc />
|
||||
public override void ProcessDiscriminatorPropertySet(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
string? name,
|
||||
|
@ -108,7 +108,7 @@ public class CosmosDiscriminatorConvention :
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc />
|
||||
public override void ProcessEntityTypeBaseTypeChanged(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
IConventionEntityType? newBaseType,
|
||||
|
@ -145,7 +145,7 @@ public class CosmosDiscriminatorConvention :
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc />
|
||||
protected override void SetDefaultDiscriminatorValues(
|
||||
IEnumerable<IConventionEntityType> entityTypes,
|
||||
IConventionDiscriminatorBuilder discriminatorBuilder)
|
||||
|
@ -156,7 +156,7 @@ public class CosmosDiscriminatorConvention :
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc />
|
||||
public override void ProcessEntityTypeRemoved(
|
||||
IConventionModelBuilder modelBuilder,
|
||||
IConventionEntityType entityType,
|
||||
|
@ -164,7 +164,7 @@ public class CosmosDiscriminatorConvention :
|
|||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <inheritdoc />
|
||||
public virtual void ProcessEmbeddedDiscriminatorName(
|
||||
IConventionModelBuilder modelBuilder,
|
||||
string? newName,
|
||||
|
|
|
@ -51,7 +51,7 @@ public class CosmosJsonIdConvention
|
|||
/// Creates a new instance of <see cref="CosmosJsonIdConvention" />.
|
||||
/// </summary>
|
||||
/// <param name="dependencies">Parameter object containing dependencies for this convention.</param>
|
||||
/// <param name="definitionFactory">The factory to create a <see cref="IJsonIdDefinition"/> for each entity type.</param>
|
||||
/// <param name="definitionFactory">The factory to create a <see cref="IJsonIdDefinition" /> for each entity type.</param>
|
||||
public CosmosJsonIdConvention(
|
||||
ProviderConventionSetBuilderDependencies dependencies,
|
||||
IJsonIdDefinitionFactory definitionFactory)
|
||||
|
@ -66,7 +66,7 @@ public class CosmosJsonIdConvention
|
|||
protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The factory to create a <see cref="IJsonIdDefinition"/> for each entity type.
|
||||
/// The factory to create a <see cref="IJsonIdDefinition" /> for each entity type.
|
||||
/// </summary>
|
||||
protected virtual IJsonIdDefinitionFactory DefinitionFactory { get; }
|
||||
|
||||
|
@ -78,7 +78,8 @@ public class CosmosJsonIdConvention
|
|||
var primaryKey = entityType.FindPrimaryKey();
|
||||
if (entityType.BaseType != null // Requires: IEntityTypeBaseTypeChangedConvention
|
||||
|| !entityType.IsDocumentRoot() // Requires: IEntityTypeAnnotationChangedConvention (ContainerName)
|
||||
|| entityType.GetForeignKeys().Any(fk => fk.IsOwnership) // Requires: IForeignKeyOwnershipChangedConvention, IForeignKeyRemovedConvention
|
||||
|| entityType.GetForeignKeys()
|
||||
.Any(fk => fk.IsOwnership) // Requires: IForeignKeyOwnershipChangedConvention, IForeignKeyRemovedConvention
|
||||
|| primaryKey == null) // Requires: IKeyAddedConvention, IKeyRemovedConvention
|
||||
{
|
||||
// If the entity type is not a keyed, root document in the container, then it doesn't have an `id` mapping, so
|
||||
|
@ -227,6 +228,7 @@ public class CosmosJsonIdConvention
|
|||
{
|
||||
ProcessEntityType(entityTypeBuilder.Metadata, context);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CosmosAnnotationNames.HasShadowId:
|
||||
|
@ -235,12 +237,15 @@ public class CosmosJsonIdConvention
|
|||
{
|
||||
ProcessEntityType(entityTypeBuilder.Metadata, context);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void ProcessForeignKeyOwnershipChanged(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext<bool?> context)
|
||||
public virtual void ProcessForeignKeyOwnershipChanged(
|
||||
IConventionForeignKeyBuilder relationshipBuilder,
|
||||
IConventionContext<bool?> context)
|
||||
=> ProcessEntityType(relationshipBuilder.Metadata.DeclaringEntityType, context);
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -262,7 +267,9 @@ public class CosmosJsonIdConvention
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void ProcessPropertyAdded(IConventionPropertyBuilder propertyBuilder, IConventionContext<IConventionPropertyBuilder> context)
|
||||
public virtual void ProcessPropertyAdded(
|
||||
IConventionPropertyBuilder propertyBuilder,
|
||||
IConventionContext<IConventionPropertyBuilder> context)
|
||||
=> ProcessEntityType(propertyBuilder.Metadata.DeclaringType.ContainingEntityType, context);
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -188,5 +188,6 @@ public class CosmosManyToManyJoinEntityTypeConvention :
|
|||
=> skipNavigation.DeclaringEntityType.GetContainer() == skipNavigation.TargetEntityType.GetContainer()
|
||||
&& skipNavigation.DeclaringEntityType.GetPartitionKeyPropertyNames().Any()
|
||||
&& (skipNavigation.Inverse?.DeclaringEntityType.GetPartitionKeyPropertyNames()
|
||||
.SequenceEqual(skipNavigation.DeclaringEntityType.GetPartitionKeyPropertyNames(), StringComparer.Ordinal) == true);
|
||||
.SequenceEqual(skipNavigation.DeclaringEntityType.GetPartitionKeyPropertyNames(), StringComparer.Ordinal)
|
||||
== true);
|
||||
}
|
||||
|
|
|
@ -73,7 +73,6 @@ public class CosmosPartitionKeyInPrimaryKeyConvention :
|
|||
primaryKeyProperties.Add(partitionKeyProperty!);
|
||||
keyContainsPartitionProperties = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (keyContainsPartitionProperties)
|
||||
|
@ -171,10 +170,12 @@ public class CosmosPartitionKeyInPrimaryKeyConvention :
|
|||
IConventionKey? previousPrimaryKey,
|
||||
IConventionContext<IConventionKey> context)
|
||||
{
|
||||
if ((newPrimaryKey != null && newPrimaryKey.Properties
|
||||
.Any(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName))
|
||||
|| (previousPrimaryKey != null && previousPrimaryKey.Properties
|
||||
.Any(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName)))
|
||||
if ((newPrimaryKey != null
|
||||
&& newPrimaryKey.Properties
|
||||
.Any(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName))
|
||||
|| (previousPrimaryKey != null
|
||||
&& previousPrimaryKey.Properties
|
||||
.Any(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName)))
|
||||
{
|
||||
ProcessIdProperty(entityTypeBuilder);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -28,14 +28,14 @@ public class CosmosConventionSetBuilder : ProviderConventionSetBuilder
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The factory to create a <see cref="IJsonIdDefinition"/> for each entity type.
|
||||
/// The factory to create a <see cref="IJsonIdDefinition" /> for each entity type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
/// </remarks>>
|
||||
/// </remarks>
|
||||
protected virtual IJsonIdDefinitionFactory DefinitionFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the behavior for including discriminator values in the JSON "id" value.
|
||||
/// Defines the behavior for including discriminator values in the JSON "id" value.
|
||||
/// </summary>
|
||||
public enum IdDiscriminatorMode
|
||||
{
|
||||
|
|
|
@ -25,12 +25,14 @@ public static class CosmosEntityTypeExtensions
|
|||
|| entityType[CosmosAnnotationNames.ContainerName] != null);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the JSON `id` definition, or <see langword="null"/> if there is none.
|
||||
/// Returns the JSON `id` definition, or <see langword="null" /> if there is none.
|
||||
/// </summary>
|
||||
/// <param name="entityType">The entity type.</param>
|
||||
public static IJsonIdDefinition? GetJsonIdDefinition(this IEntityType entityType)
|
||||
=> entityType.GetOrAddRuntimeAnnotationValue(CosmosAnnotationNames.JsonIdDefinition,
|
||||
=> entityType.GetOrAddRuntimeAnnotationValue(
|
||||
CosmosAnnotationNames.JsonIdDefinition,
|
||||
static e =>
|
||||
((CosmosModelRuntimeInitializerDependencies)e!.Model.FindRuntimeAnnotationValue(
|
||||
CosmosAnnotationNames.ModelDependencies)!).JsonIdDefinitionFactory.Create(e),
|
||||
entityType);}
|
||||
entityType);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ public interface IJsonIdDefinition
|
|||
IReadOnlyList<IProperty> Properties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/> if the discriminator is included in the key.
|
||||
/// <see langword="true" /> if the discriminator is included in the key.
|
||||
/// </summary>
|
||||
/// <para>
|
||||
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
|
||||
|
@ -31,7 +31,7 @@ public interface IJsonIdDefinition
|
|||
bool IncludesDiscriminator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/> if the discriminator is for the root entity type.
|
||||
/// <see langword="true" /> if the discriminator is for the root entity type.
|
||||
/// </summary>
|
||||
/// <para>
|
||||
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
|
||||
|
|
|
@ -52,6 +52,7 @@ public class JsonIdDefinition : IJsonIdDefinition
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
public virtual IReadOnlyList<IProperty> Properties { get; }
|
||||
|
||||
/// <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
|
||||
|
|
|
@ -48,18 +48,19 @@ public class CosmosAliasManager
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </remarks>
|
||||
public virtual string GenerateSourceAlias(Expression expression, string? fallback = null)
|
||||
=> GenerateSourceAlias(expression switch
|
||||
{
|
||||
IAccessExpression { PropertyName: string propertyName } => propertyName,
|
||||
FromSqlExpression => "sql",
|
||||
SqlFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var array, ..] } => GenerateSourceAlias(array),
|
||||
ObjectFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var array, ..] } => GenerateSourceAlias(array),
|
||||
SqlFunctionExpression { Name: var name } => name,
|
||||
ObjectFunctionExpression { Name: var name } => name,
|
||||
ArrayConstantExpression => "array",
|
||||
=> GenerateSourceAlias(
|
||||
expression switch
|
||||
{
|
||||
IAccessExpression { PropertyName: string propertyName } => propertyName,
|
||||
FromSqlExpression => "sql",
|
||||
SqlFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var array, ..] } => GenerateSourceAlias(array),
|
||||
ObjectFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var array, ..] } => GenerateSourceAlias(array),
|
||||
SqlFunctionExpression { Name: var name } => name,
|
||||
ObjectFunctionExpression { Name: var name } => name,
|
||||
ArrayConstantExpression => "array",
|
||||
|
||||
_ => fallback ?? "value"
|
||||
});
|
||||
_ => fallback ?? "value"
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Generates an alias based on the given <paramref name="name" />.
|
||||
|
@ -145,7 +146,7 @@ public class CosmosAliasManager
|
|||
}
|
||||
else
|
||||
{
|
||||
bitmap = aliasBitmaps[aliasBase] = new(aliasNum + 1);
|
||||
bitmap = aliasBitmaps[aliasBase] = new BitArray(aliasNum + 1);
|
||||
}
|
||||
|
||||
bitmap[aliasNum] = true;
|
||||
|
@ -173,7 +174,7 @@ public class CosmosAliasManager
|
|||
var j = i - numHoles;
|
||||
var newAlias = aliasBase + (j == 0 ? "" : (j - 1).ToString());
|
||||
|
||||
aliasRewritingMap ??= new();
|
||||
aliasRewritingMap ??= new Dictionary<string, string>();
|
||||
aliasRewritingMap[oldAlias] = newAlias;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -518,7 +518,7 @@ public class CosmosQuerySqlGenerator(ITypeMappingSource typeMappingSource) : Sql
|
|||
op = " || ";
|
||||
}
|
||||
else if (sqlBinaryExpression.OperatorType == ExpressionType.ExclusiveOr
|
||||
&& sqlBinaryExpression.Type == typeof(bool))
|
||||
&& sqlBinaryExpression.Type == typeof(bool))
|
||||
{
|
||||
op = " != ";
|
||||
}
|
||||
|
@ -743,7 +743,6 @@ public class CosmosQuerySqlGenerator(ITypeMappingSource typeMappingSource) : Sql
|
|||
.Append(sourceExpression.Alias)
|
||||
.Append(" IN ");
|
||||
|
||||
|
||||
VisitContainerExpression(sourceExpression.Expression);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
public class CosmosQueryTranslationPostprocessor(
|
||||
QueryTranslationPostprocessorDependencies dependencies,
|
||||
ISqlExpressionFactory sqlExpressionFactory,
|
||||
CosmosQueryCompilationContext queryCompilationContext)
|
||||
QueryTranslationPostprocessorDependencies dependencies,
|
||||
ISqlExpressionFactory sqlExpressionFactory,
|
||||
CosmosQueryCompilationContext queryCompilationContext)
|
||||
: QueryTranslationPostprocessor(dependencies, queryCompilationContext)
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -10,8 +10,8 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
public class CosmosQueryTranslationPostprocessorFactory(
|
||||
QueryTranslationPostprocessorDependencies dependencies,
|
||||
ISqlExpressionFactory sqlExpressionFactory)
|
||||
QueryTranslationPostprocessorDependencies dependencies,
|
||||
ISqlExpressionFactory sqlExpressionFactory)
|
||||
: IQueryTranslationPostprocessorFactory
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -10,8 +10,8 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
public class CosmosQueryTranslationPreprocessor(
|
||||
QueryTranslationPreprocessorDependencies dependencies,
|
||||
CosmosQueryCompilationContext cosmosQueryCompilationContext)
|
||||
QueryTranslationPreprocessorDependencies dependencies,
|
||||
CosmosQueryCompilationContext cosmosQueryCompilationContext)
|
||||
: QueryTranslationPreprocessor(dependencies, cosmosQueryCompilationContext)
|
||||
{
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.Expressions;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
|
@ -141,12 +139,13 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
|
|||
// Wrap the shaper for the entire query in a PagingExpression which also contains the paging arguments, and update
|
||||
// the final cardinality to Single (since we'll be returning a single Page).
|
||||
return shapedQuery
|
||||
.UpdateShaperExpression(new PagingExpression(
|
||||
shapedQuery.ShaperExpression,
|
||||
translatedMaxItemCount,
|
||||
translatedContinuationToken,
|
||||
translatedResponseContinuationTokenLimitInKb,
|
||||
typeof(CosmosPage<>).MakeGenericType(shapedQuery.ShaperExpression.Type)))
|
||||
.UpdateShaperExpression(
|
||||
new PagingExpression(
|
||||
shapedQuery.ShaperExpression,
|
||||
translatedMaxItemCount,
|
||||
translatedContinuationToken,
|
||||
translatedResponseContinuationTokenLimitInKb,
|
||||
typeof(CosmosPage<>).MakeGenericType(shapedQuery.ShaperExpression.Type)))
|
||||
.UpdateResultCardinality(ResultCardinality.Single);
|
||||
}
|
||||
|
||||
|
@ -223,7 +222,7 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
|
|||
{
|
||||
#pragma warning disable EF1001 // Internal EF Core API usage.
|
||||
var translation = _sqlTranslator.Translate(
|
||||
Microsoft.EntityFrameworkCore.Infrastructure.ExpressionExtensions.CreateEFPropertyExpression(
|
||||
EntityFrameworkCore.Infrastructure.ExpressionExtensions.CreateEFPropertyExpression(
|
||||
elementAtTranslation.ShaperExpression,
|
||||
elementAtTranslation.ShaperExpression.Type,
|
||||
boundMember.Type,
|
||||
|
@ -340,8 +339,9 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
|
|||
selectExpression,
|
||||
_sqlExpressionFactory.In(
|
||||
(SqlExpression)discriminatorColumn,
|
||||
concreteEntityTypes.Select(et => _sqlExpressionFactory.Constant(et.GetDiscriminatorValue(), discriminatorColumn.Type))
|
||||
.ToArray()));
|
||||
concreteEntityTypes.Select(
|
||||
et => _sqlExpressionFactory.Constant(et.GetDiscriminatorValue(), discriminatorColumn.Type))
|
||||
.ToArray()));
|
||||
Check.DebugAssert(success, "Couldn't apply predicate when creating a new ShapedQueryExpression");
|
||||
}
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
|
|||
var simplifiedTranslation = _sqlExpressionFactory.GreaterThan(
|
||||
_sqlExpressionFactory.Function(
|
||||
"ARRAY_LENGTH", new[] { array }, typeof(int), _typeMappingSource.FindMapping(typeof(int))),
|
||||
_sqlExpressionFactory.Constant(0));
|
||||
_sqlExpressionFactory.Constant(0));
|
||||
var select = new SelectExpression(simplifiedTranslation);
|
||||
|
||||
return source.Update(select, new ProjectionBindingExpression(select, new ProjectionMember(), typeof(int)));
|
||||
|
@ -519,7 +519,7 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
|
|||
// Translate to EXISTS
|
||||
var anyLambdaParameter = Expression.Parameter(item.Type, "p");
|
||||
var anyLambda = Expression.Lambda(
|
||||
Microsoft.EntityFrameworkCore.Infrastructure.ExpressionExtensions.CreateEqualsExpression(anyLambdaParameter, item),
|
||||
EntityFrameworkCore.Infrastructure.ExpressionExtensions.CreateEqualsExpression(anyLambdaParameter, item),
|
||||
anyLambdaParameter);
|
||||
|
||||
return TranslateAny(source, anyLambda);
|
||||
|
@ -598,7 +598,7 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
|
|||
// ElementAtOrDefault over an array of scalars
|
||||
case SqlExpression scalarArray when projection is SqlExpression element:
|
||||
{
|
||||
SqlExpression translation = _sqlExpressionFactory.ArrayIndex(
|
||||
var translation = _sqlExpressionFactory.ArrayIndex(
|
||||
scalarArray, translatedIndex, element.Type, element.TypeMapping);
|
||||
|
||||
// ElementAt may access indexes beyond the end of the array; Cosmos returns undefined for those cases.
|
||||
|
@ -633,7 +633,8 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
|
|||
}
|
||||
|
||||
var translatedSelect =
|
||||
new SelectExpression(new EntityProjectionExpression(translation, (IEntityType)projectedStructuralTypeShaper.StructuralType));
|
||||
new SelectExpression(
|
||||
new EntityProjectionExpression(translation, (IEntityType)projectedStructuralTypeShaper.StructuralType));
|
||||
return source.Update(
|
||||
translatedSelect,
|
||||
new StructuralTypeShaperExpression(
|
||||
|
@ -1283,7 +1284,10 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
|
|||
case SqlExpression scalarArray when projection is SqlExpression element:
|
||||
{
|
||||
// Take() is composed over Skip(), combine the two together to a single ARRAY_SLICE()
|
||||
var slice = array is SqlFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var nestedArray, var skipCount] } previousSlice
|
||||
var slice = array is SqlFunctionExpression
|
||||
{
|
||||
Name: "ARRAY_SLICE", Arguments: [var nestedArray, var skipCount]
|
||||
} previousSlice
|
||||
? previousSlice.Update([nestedArray, skipCount, translatedCount])
|
||||
: _sqlExpressionFactory.Function(
|
||||
"ARRAY_SLICE", [scalarArray, TranslateExpression(Expression.Constant(0))!, translatedCount], scalarArray.Type,
|
||||
|
@ -1301,10 +1305,14 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
|
|||
case not null when projectedStructuralTypeShaper is not null:
|
||||
{
|
||||
// Take() is composed over Skip(), combine the two together to a single ARRAY_SLICE()
|
||||
var slice = array is ObjectFunctionExpression { Name: "ARRAY_SLICE", Arguments: [var nestedArray, var skipCount] } previousSlice
|
||||
var slice = array is ObjectFunctionExpression
|
||||
{
|
||||
Name: "ARRAY_SLICE", Arguments: [var nestedArray, var skipCount]
|
||||
} previousSlice
|
||||
? previousSlice.Update([nestedArray, skipCount, translatedCount])
|
||||
: new ObjectFunctionExpression(
|
||||
"ARRAY_SLICE", [array, TranslateExpression(Expression.Constant(0))!, translatedCount], projectedStructuralTypeShaper.Type);
|
||||
"ARRAY_SLICE", [array, TranslateExpression(Expression.Constant(0))!, translatedCount],
|
||||
projectedStructuralTypeShaper.Type);
|
||||
|
||||
var alias = _aliasManager.GenerateSourceAlias(slice);
|
||||
var translatedSelect = SelectExpression.CreateForCollection(
|
||||
|
|
|
@ -271,6 +271,7 @@ public class CosmosReadItemAndPartitionKeysExtractor : ExpressionVisitor
|
|||
_jsonIdPropertyValues[property] = propertyValue;
|
||||
isCompatibleComparisonForReadItem = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ public partial class CosmosShapedQueryCompilingExpressionVisitor
|
|||
{
|
||||
storeName = projection.Alias;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -114,7 +115,8 @@ public partial class CosmosShapedQueryCompilingExpressionVisitor
|
|||
{
|
||||
case ObjectArrayAccessExpression objectArrayProjectionExpression:
|
||||
_projectionBindings[objectArrayProjectionExpression] = parameterExpression;
|
||||
valueExpression = CreateGetValueExpression(objectArrayProjectionExpression.Object, storeName, parameterExpression.Type);
|
||||
valueExpression = CreateGetValueExpression(
|
||||
objectArrayProjectionExpression.Object, storeName, parameterExpression.Type);
|
||||
break;
|
||||
|
||||
case EntityProjectionExpression entityProjectionExpression:
|
||||
|
@ -144,11 +146,13 @@ public partial class CosmosShapedQueryCompilingExpressionVisitor
|
|||
{
|
||||
valueExpression = CreateGetValueExpression(valueExpression, storeNames[i], typeof(JObject));
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException(
|
||||
CoreStrings.TranslationFailed(binaryExpression.Print()));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#nullable disable
|
||||
|
||||
using System.Collections;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Internal;
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
|
@ -37,6 +36,7 @@ public partial class CosmosShapedQueryCompilingExpressionVisitor
|
|||
{
|
||||
mutableValues.Add(sqlExpressionFactory.Constant(value, value?.GetType() ?? typeof(object), typeMapping));
|
||||
}
|
||||
|
||||
values = mutableValues;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
|
||||
#nullable disable
|
||||
|
||||
using System.Collections;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Diagnostics.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
|
|
|
@ -74,7 +74,8 @@ public partial class CosmosShapedQueryCompilingExpressionVisitor
|
|||
private bool TryGetResourceId(out string resourceId)
|
||||
{
|
||||
var jsonIdDefinition = _rootEntityType.GetJsonIdDefinition();
|
||||
Check.DebugAssert(jsonIdDefinition != null,
|
||||
Check.DebugAssert(
|
||||
jsonIdDefinition != null,
|
||||
"Should not be using this enumerable if not using ReadItem, which needs an id definition.");
|
||||
|
||||
var values = new List<object>(jsonIdDefinition.Properties.Count);
|
||||
|
|
|
@ -15,12 +15,12 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
public class CosmosSqlTranslatingExpressionVisitor(
|
||||
QueryCompilationContext queryCompilationContext,
|
||||
ISqlExpressionFactory sqlExpressionFactory,
|
||||
ITypeMappingSource typeMappingSource,
|
||||
IMemberTranslatorProvider memberTranslatorProvider,
|
||||
IMethodCallTranslatorProvider methodCallTranslatorProvider,
|
||||
QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor)
|
||||
QueryCompilationContext queryCompilationContext,
|
||||
ISqlExpressionFactory sqlExpressionFactory,
|
||||
ITypeMappingSource typeMappingSource,
|
||||
IMemberTranslatorProvider memberTranslatorProvider,
|
||||
IMethodCallTranslatorProvider methodCallTranslatorProvider,
|
||||
QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor)
|
||||
: ExpressionVisitor
|
||||
{
|
||||
private const string RuntimeParameterPrefix = QueryCompilationContext.QueryParameterPrefix + "entity_equality_";
|
||||
|
@ -346,22 +346,22 @@ public class CosmosSqlTranslatingExpressionVisitor(
|
|||
case StructuralTypeShaperExpression shaper:
|
||||
return new EntityReferenceExpression(shaper);
|
||||
|
||||
// var result = Visit(entityShaperExpression.ValueBufferExpression);
|
||||
//
|
||||
// if (result is UnaryExpression
|
||||
// {
|
||||
// NodeType: ExpressionType.Convert,
|
||||
// Operand.NodeType: ExpressionType.Convert
|
||||
// } outerUnary
|
||||
// && outerUnary.Type == typeof(ValueBuffer)
|
||||
// && outerUnary.Operand.Type == typeof(object))
|
||||
// {
|
||||
// result = ((UnaryExpression)outerUnary.Operand).Operand;
|
||||
// }
|
||||
//
|
||||
// return result is EntityProjectionExpression entityProjectionExpression
|
||||
// ? new EntityReferenceExpression(entityProjectionExpression)
|
||||
// : QueryCompilationContext.NotTranslatedExpression;
|
||||
// var result = Visit(entityShaperExpression.ValueBufferExpression);
|
||||
//
|
||||
// if (result is UnaryExpression
|
||||
// {
|
||||
// NodeType: ExpressionType.Convert,
|
||||
// Operand.NodeType: ExpressionType.Convert
|
||||
// } outerUnary
|
||||
// && outerUnary.Type == typeof(ValueBuffer)
|
||||
// && outerUnary.Operand.Type == typeof(object))
|
||||
// {
|
||||
// result = ((UnaryExpression)outerUnary.Operand).Operand;
|
||||
// }
|
||||
//
|
||||
// return result is EntityProjectionExpression entityProjectionExpression
|
||||
// ? new EntityReferenceExpression(entityProjectionExpression)
|
||||
// : QueryCompilationContext.NotTranslatedExpression;
|
||||
|
||||
case ProjectionBindingExpression projectionBindingExpression:
|
||||
return projectionBindingExpression.ProjectionMember != null
|
||||
|
@ -855,7 +855,7 @@ public class CosmosSqlTranslatingExpressionVisitor(
|
|||
MemberIdentity.Create(entityType.GetDiscriminatorPropertyName()),
|
||||
out var discriminatorMember,
|
||||
out _)
|
||||
&& discriminatorMember is SqlExpression discriminatorColumn)
|
||||
&& discriminatorMember is SqlExpression discriminatorColumn)
|
||||
{
|
||||
var concreteEntityTypes = derivedType.GetConcreteDerivedTypesInclusive().ToList();
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal;
|
||||
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -85,7 +85,7 @@ public class ObjectBinaryExpression : Expression, IPrintableExpression
|
|||
/// </summary>
|
||||
protected override Expression VisitChildren(ExpressionVisitor visitor)
|
||||
{
|
||||
var left = (Expression)visitor.Visit(Left);
|
||||
var left = visitor.Visit(Left);
|
||||
var right = (Expression)visitor.Visit(Right);
|
||||
|
||||
return Update(left, right);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
@ -27,5 +28,7 @@ public class ReadItemInfo
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
public ReadItemInfo(IDictionary<IProperty, Expression> propertyValues)
|
||||
=> PropertyValues = propertyValues;
|
||||
{
|
||||
PropertyValues = propertyValues;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
@ -63,7 +63,9 @@ public sealed class SelectExpression : Expression, IPrintableExpression
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
public SelectExpression(Expression projection)
|
||||
=> _projectionMapping[new ProjectionMember()] = projection;
|
||||
{
|
||||
_projectionMapping[new ProjectionMember()] = projection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
|
||||
|
@ -534,7 +536,7 @@ public sealed class SelectExpression : Expression, IPrintableExpression
|
|||
/// 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 sealed override ExpressionType NodeType
|
||||
public override ExpressionType NodeType
|
||||
=> ExpressionType.Extension;
|
||||
|
||||
/// <summary>
|
||||
|
@ -632,8 +634,7 @@ public sealed class SelectExpression : Expression, IPrintableExpression
|
|||
|
||||
return new SelectExpression(sources, predicate, projections, IsDistinct, orderings, offset, limit)
|
||||
{
|
||||
_projectionMapping = projectionMapping,
|
||||
ReadItemInfo = ReadItemInfo
|
||||
_projectionMapping = projectionMapping, ReadItemInfo = ReadItemInfo
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -646,8 +647,7 @@ public sealed class SelectExpression : Expression, IPrintableExpression
|
|||
public SelectExpression WithReadItemInfo(ReadItemInfo readItemInfo)
|
||||
=> new(Sources.ToList(), Predicate, Projection.ToList(), IsDistinct, Orderings.ToList(), Offset, Limit)
|
||||
{
|
||||
_projectionMapping = _projectionMapping,
|
||||
ReadItemInfo = readItemInfo
|
||||
_projectionMapping = _projectionMapping, ReadItemInfo = readItemInfo
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -25,7 +25,9 @@ public class SqlConstantExpression : SqlExpression
|
|||
/// </summary>
|
||||
public SqlConstantExpression(object? value, Type type, CoreTypeMapping? typeMapping)
|
||||
: base(type.UnwrapNullableType(), typeMapping)
|
||||
=> Value = value;
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -282,5 +282,4 @@ public interface ISqlExpressionFactory
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
SqlExpression Constant(object? value, Type type, CoreTypeMapping? typeMapping = null);
|
||||
|
||||
}
|
||||
|
|
|
@ -166,7 +166,9 @@ public class SqlExpressionFactory(ITypeMappingSource typeMappingSource, IModel m
|
|||
// TODO: This infers based on the CLR type; need to properly infer based on the element type mapping
|
||||
// TODO: being applied here (e.g. WHERE @p[1] = c.PropertyWithValueConverter). #34026
|
||||
var arrayTypeMapping = left.TypeMapping
|
||||
?? (typeMapping is null ? null : typeMappingSource.FindMapping(typeof(IEnumerable<>).MakeGenericType(typeMapping.ClrType)));
|
||||
?? (typeMapping is null
|
||||
? null
|
||||
: typeMappingSource.FindMapping(typeof(IEnumerable<>).MakeGenericType(typeMapping.ClrType)));
|
||||
return new SqlBinaryExpression(
|
||||
ExpressionType.ArrayIndex,
|
||||
ApplyTypeMapping(left, arrayTypeMapping),
|
||||
|
@ -435,12 +437,14 @@ public class SqlExpressionFactory(ITypeMappingSource typeMappingSource, IModel m
|
|||
{
|
||||
return left;
|
||||
}
|
||||
|
||||
// true && x -> x
|
||||
// x && false -> false
|
||||
if (left is SqlConstantExpression { Value: true } || right is SqlConstantExpression { Value: false })
|
||||
{
|
||||
return right;
|
||||
}
|
||||
|
||||
// x is null && x is not null -> false
|
||||
// x is not null && x is null -> false
|
||||
if (left is SqlUnaryExpression { OperatorType: ExpressionType.Equal or ExpressionType.NotEqual } leftUnary
|
||||
|
@ -450,6 +454,7 @@ public class SqlExpressionFactory(ITypeMappingSource typeMappingSource, IModel m
|
|||
// the case in which left and right are the same expression is handled above
|
||||
return Constant(false);
|
||||
}
|
||||
|
||||
if (existingExpression is SqlBinaryExpression { OperatorType: ExpressionType.AndAlso } binaryExpr
|
||||
&& left == binaryExpr.Left
|
||||
&& right == binaryExpr.Right)
|
||||
|
@ -480,6 +485,7 @@ public class SqlExpressionFactory(ITypeMappingSource typeMappingSource, IModel m
|
|||
{
|
||||
return left;
|
||||
}
|
||||
|
||||
// false || x -> x
|
||||
// x || true -> true
|
||||
if (left is SqlConstantExpression { Value: false }
|
||||
|
@ -487,6 +493,7 @@ public class SqlExpressionFactory(ITypeMappingSource typeMappingSource, IModel m
|
|||
{
|
||||
return right;
|
||||
}
|
||||
|
||||
// x is null || x is not null -> true
|
||||
// x is not null || x is null -> true
|
||||
if (left is SqlUnaryExpression { OperatorType: ExpressionType.Equal or ExpressionType.NotEqual } leftUnary
|
||||
|
@ -496,6 +503,7 @@ public class SqlExpressionFactory(ITypeMappingSource typeMappingSource, IModel m
|
|||
// the case in which left and right are the same expression is handled above
|
||||
return Constant(true);
|
||||
}
|
||||
|
||||
if (existingExpression is SqlBinaryExpression { OperatorType: ExpressionType.OrElse } binaryExpr
|
||||
&& left == binaryExpr.Left
|
||||
&& right == binaryExpr.Right)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -132,6 +132,7 @@ public class CosmosDatabaseCreator : IDatabaseCreator
|
|||
{
|
||||
partitionKeyStoreNames = GetPartitionKeyStoreNames(entityType);
|
||||
}
|
||||
|
||||
analyticalTtl ??= entityType.GetAnalyticalStoreTimeToLive();
|
||||
defaultTtl ??= entityType.GetDefaultTimeToLive();
|
||||
throughput ??= entityType.GetThroughput();
|
||||
|
@ -208,8 +209,8 @@ public class CosmosDatabaseCreator : IDatabaseCreator
|
|||
public virtual void SeedData(bool created)
|
||||
{
|
||||
var coreOptionsExtension =
|
||||
_contextOptions.FindExtension<CoreOptionsExtension>()
|
||||
?? new CoreOptionsExtension();
|
||||
_contextOptions.FindExtension<CoreOptionsExtension>()
|
||||
?? new CoreOptionsExtension();
|
||||
|
||||
var seed = coreOptionsExtension.Seeder;
|
||||
if (seed != null)
|
||||
|
|
|
@ -39,7 +39,6 @@ public class CosmosTypeMappingSource : TypeMappingSource
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
/// <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
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Storage.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal;
|
||||
|
||||
|
@ -24,9 +23,9 @@ public class CosmosVectorTypeMapping : CosmosTypeMapping
|
|||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
public static new CosmosVectorTypeMapping Default { get; }
|
||||
// Note that this default is not valid because dimensions cannot be zero. But since there is no reasonable
|
||||
// default dimensions size for a vector type, this is intentionally not valid rather than just being wrong.
|
||||
// The fundamental problem here is that type mappings are "required" to have some default now.
|
||||
// Note that this default is not valid because dimensions cannot be zero. But since there is no reasonable
|
||||
// default dimensions size for a vector type, this is intentionally not valid rather than just being wrong.
|
||||
// The fundamental problem here is that type mappings are "required" to have some default now.
|
||||
= new(typeof(byte[]), new CosmosVectorType(DistanceFunction.Cosine, 0));
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -56,7 +56,7 @@ public class ReadOnlyMemoryConverter<T> : ValueConverter<ReadOnlyMemory<T>, T[]>
|
|||
public static ReadOnlyMemory<T> ToMemory(T[] array)
|
||||
// If the array is empty, then return the default ReadOnlyMemory instance because this will compare the same as other empty
|
||||
// ReadOnlyMemory instances, while the instance created with an empty array is considered not equal to the default.
|
||||
=> array.Length == 0 ? default : new(array);
|
||||
=> array.Length == 0 ? default : new ReadOnlyMemory<T>(array);
|
||||
|
||||
/// <summary>
|
||||
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
|
||||
|
|
|
@ -8,11 +8,8 @@ using System.Runtime.CompilerServices;
|
|||
using System.Security;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Editing;
|
||||
using Microsoft.CodeAnalysis.Simplification;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
||||
|
||||
|
@ -1024,11 +1021,11 @@ public class CSharpHelper : ICSharpHelper
|
|||
}
|
||||
|
||||
return allValues.Aggregate(
|
||||
(string?)null,
|
||||
(previous, current) =>
|
||||
previous == null
|
||||
? GetSimpleEnumValue(type, Enum.GetName(type, current)!, fullName)
|
||||
: previous + " | " + GetSimpleEnumValue(type, Enum.GetName(type, current)!, fullName))
|
||||
(string?)null,
|
||||
(previous, current) =>
|
||||
previous == null
|
||||
? GetSimpleEnumValue(type, Enum.GetName(type, current)!, fullName)
|
||||
: previous + " | " + GetSimpleEnumValue(type, Enum.GetName(type, current)!, fullName))
|
||||
?? $"({Reference(type)}){UnknownLiteral(Convert.ChangeType(flags, Enum.GetUnderlyingType(type)))}";
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ using System.Text;
|
|||
using Microsoft.Build.Locator;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Editing;
|
||||
using Microsoft.CodeAnalysis.Formatting;
|
||||
using Microsoft.CodeAnalysis.MSBuild;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
|
@ -201,8 +200,9 @@ public class DbContextOperations
|
|||
if (scaffoldModel
|
||||
&& (!optimizeAllInAssembly || contextType.Assembly == _assembly))
|
||||
{
|
||||
generatedFiles.AddRange(ScaffoldCompiledModel(
|
||||
outputDir, modelNamespace, context, suffix, nativeAot, services, generatedFileNames));
|
||||
generatedFiles.AddRange(
|
||||
ScaffoldCompiledModel(
|
||||
outputDir, modelNamespace, context, suffix, nativeAot, services, generatedFileNames));
|
||||
if (precompileQueries)
|
||||
{
|
||||
memberAccessReplacements = ((IRuntimeModel)context.GetService<IDesignTimeModel>().Model).GetUnsafeAccessors();
|
||||
|
@ -211,13 +211,14 @@ public class DbContextOperations
|
|||
|
||||
if (precompileQueries)
|
||||
{
|
||||
generatedFiles.AddRange(PrecompileQueries(
|
||||
outputDir,
|
||||
context,
|
||||
suffix,
|
||||
services,
|
||||
memberAccessReplacements ?? ((IRuntimeModel)context.Model).GetUnsafeAccessors(),
|
||||
generatedFileNames));
|
||||
generatedFiles.AddRange(
|
||||
PrecompileQueries(
|
||||
outputDir,
|
||||
context,
|
||||
suffix,
|
||||
services,
|
||||
memberAccessReplacements ?? ((IRuntimeModel)context.Model).GetUnsafeAccessors(),
|
||||
generatedFileNames));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,8 +234,9 @@ public class DbContextOperations
|
|||
var contextType = context.GetType();
|
||||
if (contextType.Assembly != _assembly)
|
||||
{
|
||||
_reporter.WriteWarning(DesignStrings.ContextAssemblyMismatch(
|
||||
_assembly.GetName().Name, contextType.ShortDisplayName(), contextType.Assembly.GetName().Name));
|
||||
_reporter.WriteWarning(
|
||||
DesignStrings.ContextAssemblyMismatch(
|
||||
_assembly.GetName().Name, contextType.ShortDisplayName(), contextType.Assembly.GetName().Name));
|
||||
}
|
||||
|
||||
if (outputDir == null)
|
||||
|
@ -286,7 +288,13 @@ public class DbContextOperations
|
|||
return scaffoldedFiles;
|
||||
}
|
||||
|
||||
private IReadOnlyList<string> PrecompileQueries(string? outputDir, DbContext context, string? suffix, IServiceProvider services, IReadOnlyDictionary<MemberInfo, QualifiedName> memberAccessReplacements, ISet<string> generatedFileNames)
|
||||
private IReadOnlyList<string> PrecompileQueries(
|
||||
string? outputDir,
|
||||
DbContext context,
|
||||
string? suffix,
|
||||
IServiceProvider services,
|
||||
IReadOnlyDictionary<MemberInfo, QualifiedName> memberAccessReplacements,
|
||||
ISet<string> generatedFileNames)
|
||||
{
|
||||
outputDir = Path.GetFullPath(Path.Combine(_projectDir, outputDir ?? "Generated"));
|
||||
|
||||
|
@ -294,6 +302,7 @@ public class DbContextOperations
|
|||
{
|
||||
MSBuildLocator.RegisterDefaults();
|
||||
}
|
||||
|
||||
// TODO: pass through properties
|
||||
var workspace = MSBuildWorkspace.Create();
|
||||
workspace.LoadMetadataForReferencedProjects = true;
|
||||
|
@ -302,6 +311,7 @@ public class DbContextOperations
|
|||
{
|
||||
throw new NotSupportedException(DesignStrings.UncompilableProject(_project));
|
||||
}
|
||||
|
||||
var compilation = project.GetCompilationAsync().GetAwaiter().GetResult()!;
|
||||
var errorDiagnostics = compilation.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).ToArray();
|
||||
if (errorDiagnostics.Any())
|
||||
|
@ -465,8 +475,9 @@ public class DbContextOperations
|
|||
ex = ex.InnerException!;
|
||||
}
|
||||
|
||||
throw new OperationException(DesignStrings.CannotCreateContextInstance(
|
||||
contextType ?? contextPair.Key.GetType().ShortDisplayName(), ex.Message), ex);
|
||||
throw new OperationException(
|
||||
DesignStrings.CannotCreateContextInstance(
|
||||
contextType ?? contextPair.Key.GetType().ShortDisplayName(), ex.Message), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -543,16 +543,18 @@ public class OperationExecutor : MarshalByRefObject
|
|||
var precompileQueries = (bool)(args["precompileQueries"] ?? false);
|
||||
var nativeAot = (bool)(args["nativeAot"] ?? false);
|
||||
|
||||
Execute(() => executor.OptimizeContextImpl(
|
||||
outputDir,
|
||||
modelNamespace,
|
||||
contextType,
|
||||
suffix,
|
||||
scaffoldModel,
|
||||
precompileQueries,
|
||||
nativeAot));
|
||||
Execute(
|
||||
() => executor.OptimizeContextImpl(
|
||||
outputDir,
|
||||
modelNamespace,
|
||||
contextType,
|
||||
suffix,
|
||||
scaffoldModel,
|
||||
precompileQueries,
|
||||
nativeAot));
|
||||
}
|
||||
}
|
||||
|
||||
private IReadOnlyList<string> OptimizeContextImpl(
|
||||
string? outputDir,
|
||||
string? modelNamespace,
|
||||
|
|
|
@ -78,9 +78,9 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
/// </summary>
|
||||
/// <param name="node">The Roslyn syntax node to be translated.</param>
|
||||
/// <param name="semanticModel">
|
||||
/// The <see cref="SemanticModel" /> for the Roslyn <see cref="SyntaxTree" /> of which <paramref name="node" /> is a part.
|
||||
/// The <see cref="SemanticModel" /> for the Roslyn <see cref="SyntaxTree" /> of which <paramref name="node" /> is a part.
|
||||
/// </param>
|
||||
/// <returns>A LINQ expression tree translated from the provided <paramref name="node"/>.</returns>
|
||||
/// <returns>A LINQ expression tree translated from the provided <paramref name="node" />.</returns>
|
||||
/// <remarks>
|
||||
/// 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
|
||||
|
@ -158,8 +158,9 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
|
||||
var position = Array.FindIndex(parameters, p => p.Name == name);
|
||||
var parameter = parameters[position];
|
||||
var parameterType = ResolveType(parameter.Type) ?? throw new InvalidOperationException(
|
||||
"Could not resolve type symbol for: " + parameter.Type);
|
||||
var parameterType = ResolveType(parameter.Type)
|
||||
?? throw new InvalidOperationException(
|
||||
"Could not resolve type symbol for: " + parameter.Type);
|
||||
|
||||
parameterInfos[position] = new FakeParameterInfo(name, parameterType, position);
|
||||
arguments[position] = Visit(initializer.Expression);
|
||||
|
@ -240,7 +241,8 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
// String concatenation
|
||||
SyntaxKind.AddExpression
|
||||
when left.Type == typeof(string) && right.Type == typeof(string)
|
||||
=> Add(left, right,
|
||||
=> Add(
|
||||
left, right,
|
||||
_stringConcatMethod ??=
|
||||
typeof(string).GetMethod(nameof(string.Concat), new[] { typeof(string), typeof(string) })),
|
||||
|
||||
|
@ -258,11 +260,15 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
// For bitwise operations over enums, we cast the enum to its underlying type before the bitwise operation, and then back to the
|
||||
// enum afterwards (this is corresponds to the LINQ expression tree that the compiler generates)
|
||||
SyntaxKind.BitwiseOrExpression when left.Type.IsEnum || right.Type.IsEnum
|
||||
=> Convert(Or(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type),
|
||||
=> Convert(
|
||||
Or(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type),
|
||||
SyntaxKind.BitwiseAndExpression when left.Type.IsEnum || right.Type.IsEnum
|
||||
=> Convert(And(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type),
|
||||
=> Convert(
|
||||
And(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type),
|
||||
SyntaxKind.ExclusiveOrExpression when left.Type.IsEnum || right.Type.IsEnum
|
||||
=> Convert(ExclusiveOr(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())), left.Type),
|
||||
=> Convert(
|
||||
ExclusiveOr(Convert(left, left.Type.GetEnumUnderlyingType()), Convert(right, right.Type.GetEnumUnderlyingType())),
|
||||
left.Type),
|
||||
|
||||
SyntaxKind.BitwiseOrExpression => Or(left, right),
|
||||
SyntaxKind.BitwiseAndExpression => And(left, right),
|
||||
|
@ -274,14 +280,16 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
SyntaxKind.LessThanOrEqualExpression => LessThanOrEqual(left, right),
|
||||
SyntaxKind.GreaterThanExpression => GreaterThan(left, right),
|
||||
SyntaxKind.GreaterThanOrEqualExpression => GreaterThanOrEqual(left, right),
|
||||
SyntaxKind.IsExpression => TypeIs(left, right is ConstantExpression { Value : Type type }
|
||||
? type
|
||||
: throw new InvalidOperationException(
|
||||
$"Encountered {SyntaxKind.IsExpression} with non-constant type right argument: {right}")),
|
||||
SyntaxKind.AsExpression => TypeAs(left, right is ConstantExpression { Value : Type type }
|
||||
? type
|
||||
: throw new InvalidOperationException(
|
||||
$"Encountered {SyntaxKind.AsExpression} with non-constant type right argument: {right}")),
|
||||
SyntaxKind.IsExpression => TypeIs(
|
||||
left, right is ConstantExpression { Value : Type type }
|
||||
? type
|
||||
: throw new InvalidOperationException(
|
||||
$"Encountered {SyntaxKind.IsExpression} with non-constant type right argument: {right}")),
|
||||
SyntaxKind.AsExpression => TypeAs(
|
||||
left, right is ConstantExpression { Value : Type type }
|
||||
? type
|
||||
: throw new InvalidOperationException(
|
||||
$"Encountered {SyntaxKind.AsExpression} with non-constant type right argument: {right}")),
|
||||
SyntaxKind.CoalesceExpression => Coalesce(left, right),
|
||||
|
||||
_ => throw new ArgumentOutOfRangeException($"BinaryExpressionSyntax with {binary.Kind()}")
|
||||
|
@ -323,7 +331,8 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
switch (_semanticModel.GetTypeInfo(elementAccessExpression.Expression).ConvertedType)
|
||||
{
|
||||
case IArrayTypeSymbol:
|
||||
Check.DebugAssert(elementAccessExpression.ArgumentList.Arguments.Count == 1,
|
||||
Check.DebugAssert(
|
||||
elementAccessExpression.ArgumentList.Arguments.Count == 1,
|
||||
$"ElementAccessExpressionSyntax over array with {arguments.Count} arguments");
|
||||
return ArrayIndex(visitedExpression, Visit(arguments[0].Expression));
|
||||
|
||||
|
@ -471,6 +480,7 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
{
|
||||
interpolationExpression = Convert(interpolationExpression, typeof(object));
|
||||
}
|
||||
|
||||
arguments.Add(interpolationExpression);
|
||||
formatBuilder.Append('{').Append(arguments.Count - 1).Append('}');
|
||||
break;
|
||||
|
@ -545,48 +555,50 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
var typeTypeParameterMap = new Dictionary<string, Type>(GetTypeTypeParameters(methodSymbol.ContainingType));
|
||||
|
||||
var definitionMethodInfos = declaringType.GetMethods()
|
||||
.Where(m =>
|
||||
{
|
||||
if (m.Name == methodSymbol.Name
|
||||
&& m.IsGenericMethodDefinition
|
||||
&& m.GetGenericArguments() is var candidateGenericArguments
|
||||
&& candidateGenericArguments.Length == originalDefinition.TypeParameters.Length
|
||||
&& m.GetParameters() is var candidateParams
|
||||
&& candidateParams.Length == originalDefinition.Parameters.Length)
|
||||
.Where(
|
||||
m =>
|
||||
{
|
||||
var methodTypeParameterMap = new Dictionary<string, Type>(typeTypeParameterMap);
|
||||
|
||||
// Prepare a dictionary that will be used to resolve generic type parameters (ITypeParameterSymbol) to the
|
||||
// corresponding reflection Type. This is needed to correctly (and recursively) resolve the type of parameters
|
||||
// below.
|
||||
foreach (var (symbol, type) in methodSymbol.TypeParameters.Zip(candidateGenericArguments))
|
||||
if (m.Name == methodSymbol.Name
|
||||
&& m.IsGenericMethodDefinition
|
||||
&& m.GetGenericArguments() is var candidateGenericArguments
|
||||
&& candidateGenericArguments.Length == originalDefinition.TypeParameters.Length
|
||||
&& m.GetParameters() is var candidateParams
|
||||
&& candidateParams.Length == originalDefinition.Parameters.Length)
|
||||
{
|
||||
if (symbol.Name != type.Name)
|
||||
var methodTypeParameterMap = new Dictionary<string, Type>(typeTypeParameterMap);
|
||||
|
||||
// Prepare a dictionary that will be used to resolve generic type parameters (ITypeParameterSymbol) to the
|
||||
// corresponding reflection Type. This is needed to correctly (and recursively) resolve the type of parameters
|
||||
// below.
|
||||
foreach (var (symbol, type) in methodSymbol.TypeParameters.Zip(candidateGenericArguments))
|
||||
{
|
||||
return false;
|
||||
if (symbol.Name != type.Name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
methodTypeParameterMap[symbol.Name] = type;
|
||||
}
|
||||
|
||||
methodTypeParameterMap[symbol.Name] = type;
|
||||
}
|
||||
|
||||
for (var i = 0; i < candidateParams.Length; i++)
|
||||
{
|
||||
var translatedParamType = ResolveType(originalDefinition.Parameters[i].Type, methodTypeParameterMap);
|
||||
if (translatedParamType != candidateParams[i].ParameterType)
|
||||
for (var i = 0; i < candidateParams.Length; i++)
|
||||
{
|
||||
return false;
|
||||
var translatedParamType = ResolveType(originalDefinition.Parameters[i].Type, methodTypeParameterMap);
|
||||
if (translatedParamType != candidateParams[i].ParameterType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).ToArray();
|
||||
return false;
|
||||
}).ToArray();
|
||||
|
||||
if (definitionMethodInfos.Length != 1)
|
||||
{
|
||||
throw new InvalidOperationException($"Invocation: Found {definitionMethodInfos.Length} matches for generic method: {invocation}");
|
||||
throw new InvalidOperationException(
|
||||
$"Invocation: Found {definitionMethodInfos.Length} matches for generic method: {invocation}");
|
||||
}
|
||||
|
||||
var definitionMethodInfo = definitionMethodInfos[0];
|
||||
|
@ -1025,8 +1037,8 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
var translatedParameters = new List<ParameterExpression>();
|
||||
foreach (var parameter in lambdaParameters)
|
||||
{
|
||||
if (_semanticModel.GetDeclaredSymbol(parameter) is not { } parameterSymbol ||
|
||||
ResolveType(parameterSymbol.Type) is not { } parameterType)
|
||||
if (_semanticModel.GetDeclaredSymbol(parameter) is not { } parameterSymbol
|
||||
|| ResolveType(parameterSymbol.Type) is not { } parameterType)
|
||||
{
|
||||
throw new InvalidOperationException("Could not found symbol for parameter lambda: " + parameter);
|
||||
}
|
||||
|
@ -1034,8 +1046,11 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
translatedParameters.Add(Parameter(parameterType, parameter.Identifier.Text));
|
||||
}
|
||||
|
||||
_parameterStack.Push(_parameterStack.Peek()
|
||||
.AddRange(translatedParameters.Select(p => new KeyValuePair<string, ParameterExpression>(p.Name ?? throw new NotImplementedException(), p))));
|
||||
_parameterStack.Push(
|
||||
_parameterStack.Peek()
|
||||
.AddRange(
|
||||
translatedParameters.Select(
|
||||
p => new KeyValuePair<string, ParameterExpression>(p.Name ?? throw new NotImplementedException(), p))));
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -1074,7 +1089,8 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
case INamedTypeSymbol { IsAnonymousType: true } anonymousTypeSymbol:
|
||||
_anonymousTypeDefinitions ??= LoadAnonymousTypes(anonymousTypeSymbol.ContainingAssembly);
|
||||
var properties = anonymousTypeSymbol.GetMembers().OfType<IPropertySymbol>().ToArray();
|
||||
var found = _anonymousTypeDefinitions.TryGetValue(properties.Select(p => p.Name).ToArray(),
|
||||
var found = _anonymousTypeDefinitions.TryGetValue(
|
||||
properties.Select(p => p.Name).ToArray(),
|
||||
out var anonymousTypeGenericDefinition);
|
||||
Check.DebugAssert(found, "Anonymous type not found");
|
||||
|
||||
|
@ -1241,7 +1257,8 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
|
||||
public override string Name { get; } = name;
|
||||
|
||||
public override Type? ReflectedType => null;
|
||||
public override Type? ReflectedType
|
||||
=> null;
|
||||
|
||||
// We implement GetValue since ExpressionTreeFuncletizer calls it to get the parameter value. In AOT generation time, we obviously
|
||||
// have no parameter values, nor do we need them for the first part of the query pipeline.
|
||||
|
@ -1252,7 +1269,11 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
? "<dummy>"
|
||||
: null;
|
||||
|
||||
public override void SetValue(object? obj, object? value, BindingFlags invokeAttr, Binder? binder,
|
||||
public override void SetValue(
|
||||
object? obj,
|
||||
object? value,
|
||||
BindingFlags invokeAttr,
|
||||
Binder? binder,
|
||||
CultureInfo? culture)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
|
@ -1296,11 +1317,18 @@ public class CSharpToLinqTranslator : CSharpSyntaxVisitor<Expression>
|
|||
public override RuntimeMethodHandle MethodHandle
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public override object Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters,
|
||||
public override object Invoke(
|
||||
object? obj,
|
||||
BindingFlags invokeAttr,
|
||||
Binder? binder,
|
||||
object?[]? parameters,
|
||||
CultureInfo? culture)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public override object Invoke(BindingFlags invokeAttr, Binder? binder, object?[]? parameters,
|
||||
public override object Invoke(
|
||||
BindingFlags invokeAttr,
|
||||
Binder? binder,
|
||||
object?[]? parameters,
|
||||
CultureInfo? culture)
|
||||
=> throw new NotSupportedException();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ using Microsoft.CodeAnalysis.Editing;
|
|||
using Microsoft.EntityFrameworkCore.Design.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
using Attribute = System.Attribute;
|
||||
using ConditionalExpression = System.Linq.Expressions.ConditionalExpression;
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Query.Internal;
|
||||
|
||||
|
@ -50,6 +52,7 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
{
|
||||
child.Variables.Add(parameter, name);
|
||||
}
|
||||
|
||||
child.VariableNames.UnionWith(VariableNames);
|
||||
|
||||
return child;
|
||||
|
@ -645,10 +648,8 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
{
|
||||
throw new NotImplementedException("Label on last expression of an expression block");
|
||||
}
|
||||
else
|
||||
{
|
||||
statements.Add(pendingLabeledStatement.WithStatement(EmptyStatement()));
|
||||
}
|
||||
|
||||
statements.Add(pendingLabeledStatement.WithStatement(EmptyStatement()));
|
||||
}
|
||||
|
||||
// Above we transform top-level assignments (i = 8) to var-declarations with initializers (var i = 8); those variables have
|
||||
|
@ -657,7 +658,8 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
// and either add them to the block, or lift them if we're an expression block.
|
||||
var unassignedVariableDeclarations =
|
||||
unassignedVariables.Select(
|
||||
v => (LocalDeclarationStatementSyntax)_g.LocalDeclarationStatement(Generate(v.Type), LookupVariableName(v), initializer: _g.DefaultExpression(Generate(v.Type))));
|
||||
v => (LocalDeclarationStatementSyntax)_g.LocalDeclarationStatement(
|
||||
Generate(v.Type), LookupVariableName(v), initializer: _g.DefaultExpression(Generate(v.Type))));
|
||||
|
||||
if (blockContext == ExpressionContext.Expression)
|
||||
{
|
||||
|
@ -824,7 +826,7 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
if (isFalseAbsent)
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"Missing {nameof(System.Linq.Expressions.ConditionalExpression.IfFalse)} in {nameof(System.Linq.Expressions.ConditionalExpression)} in expression context");
|
||||
$"Missing {nameof(ConditionalExpression.IfFalse)} in {nameof(ConditionalExpression)} in expression context");
|
||||
}
|
||||
|
||||
var parentLiftedState = _liftedState;
|
||||
|
@ -990,25 +992,25 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
return value switch
|
||||
{
|
||||
int or long or uint or ulong or short or sbyte or ushort or byte or double or float or decimal or char
|
||||
or string or bool or null
|
||||
or string or bool or null
|
||||
=> (ExpressionSyntax)_g.LiteralExpression(value),
|
||||
|
||||
Type t => TypeOfExpression(Generate(t)),
|
||||
Enum e => HandleEnum(e),
|
||||
|
||||
Guid g => ObjectCreationExpression(IdentifierName(nameof(Guid)))
|
||||
.WithArgumentList(
|
||||
ArgumentList(
|
||||
SingletonSeparatedList(
|
||||
Argument(
|
||||
LiteralExpression(
|
||||
SyntaxKind.StringLiteralExpression,
|
||||
Literal(g.ToString())))))),
|
||||
.WithArgumentList(
|
||||
ArgumentList(
|
||||
SingletonSeparatedList(
|
||||
Argument(
|
||||
LiteralExpression(
|
||||
SyntaxKind.StringLiteralExpression,
|
||||
Literal(g.ToString())))))),
|
||||
|
||||
ITuple tuple
|
||||
when tuple.GetType() is { IsGenericType: true } tupleType
|
||||
&& tupleType.Name.StartsWith("ValueTuple`", StringComparison.Ordinal)
|
||||
&& tupleType.Namespace == "System"
|
||||
&& tupleType.Name.StartsWith("ValueTuple`", StringComparison.Ordinal)
|
||||
&& tupleType.Namespace == "System"
|
||||
=> HandleValueTuple(tuple),
|
||||
|
||||
ReferenceEqualityComparer equalityComparer
|
||||
|
@ -1184,7 +1186,8 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
|
||||
throw new NotSupportedException(
|
||||
$"Encountered a constant of unsupported type '{value.GetType().Name}'. Only primitive constant nodes are supported."
|
||||
+ Environment.NewLine + value);
|
||||
+ Environment.NewLine
|
||||
+ value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -1339,6 +1342,7 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
genericArguments.Add(syntax);
|
||||
}
|
||||
|
||||
|
@ -1362,7 +1366,8 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
if (type.IsArray)
|
||||
{
|
||||
result = ArrayType(Generate(type.GetElementType()!))
|
||||
.WithRankSpecifiers(SingletonList(ArrayRankSpecifier(SingletonSeparatedList<ExpressionSyntax>(OmittedArraySizeExpression()))));
|
||||
.WithRankSpecifiers(
|
||||
SingletonList(ArrayRankSpecifier(SingletonSeparatedList<ExpressionSyntax>(OmittedArraySizeExpression()))));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1537,7 +1542,7 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
SeparatedList(
|
||||
lambda.Parameters.Select(
|
||||
p => Parameter(Identifier(LookupVariableName(p)))
|
||||
.WithType(p.Type.IsAnonymousType() ? null : Generate(p.Type))))),
|
||||
.WithType(p.Type.IsAnonymousType() ? null : Generate(p.Type))))),
|
||||
blockBody,
|
||||
expressionBody);
|
||||
|
||||
|
@ -1617,7 +1622,7 @@ public class LinqToCSharpSyntaxTranslator : ExpressionVisitor
|
|||
|
||||
case { Member: FieldInfo closureField, Expression: ConstantExpression constantExpression }
|
||||
when constantExpression.Type.Attributes.HasFlag(TypeAttributes.NestedPrivate)
|
||||
&& System.Attribute.IsDefined(constantExpression.Type, typeof(CompilerGeneratedAttribute), inherit: true):
|
||||
&& Attribute.IsDefined(constantExpression.Type, typeof(CompilerGeneratedAttribute), inherit: true):
|
||||
// Unwrap closure
|
||||
VisitConstant(Expression.Constant(closureField.GetValue(constantExpression.Value), member.Type));
|
||||
break;
|
||||
|
|
|
@ -38,8 +38,9 @@ public class PrecompiledQueryCodeGenerator : IPrecompiledQueryCodeGenerator
|
|||
|
||||
private const string InterceptorsNamespace = "Microsoft.EntityFrameworkCore.GeneratedInterceptors";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Language => "C#";
|
||||
/// <inheritdoc />
|
||||
public string? Language
|
||||
=> "C#";
|
||||
|
||||
/// <summary>
|
||||
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
|
||||
|
@ -221,7 +222,7 @@ public class PrecompiledQueryCodeGenerator : IPrecompiledQueryCodeGenerator
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
precompilationErrors.Add(new(querySyntax, e));
|
||||
precompilationErrors.Add(new QueryPrecompilationError(querySyntax, e));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -245,6 +246,7 @@ public class PrecompiledQueryCodeGenerator : IPrecompiledQueryCodeGenerator
|
|||
{
|
||||
_code.AppendLine(unsafeAccessor.NormalizeWhitespace().ToFullString());
|
||||
}
|
||||
|
||||
_code.AppendLine("#endregion Unsafe accessors");
|
||||
}
|
||||
|
||||
|
@ -314,7 +316,7 @@ namespace System.Runtime.CompilerServices
|
|||
generatedFileNames,
|
||||
".EFInterceptors" + suffix + Path.GetExtension(syntaxTree.FilePath),
|
||||
CompiledModelScaffolder.MaxFileNameLength);
|
||||
return new(name, _code.ToString());
|
||||
return new ScaffoldedFile(name, _code.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -467,7 +469,7 @@ namespace System.Runtime.CompilerServices
|
|||
? (reducedOperatorSymbol.Parameters[0].Name, reducedOperatorSymbol.Parameters[0].Type)
|
||||
: ("source", reducedOperatorSymbol.ReceiverType!);
|
||||
|
||||
if (sourceTypeSymbol is not INamedTypeSymbol { TypeArguments: [var sourceElementTypeSymbol]})
|
||||
if (sourceTypeSymbol is not INamedTypeSymbol { TypeArguments: [var sourceElementTypeSymbol] })
|
||||
{
|
||||
throw new UnreachableException($"Non-IQueryable first parameter in LINQ operator '{operatorSymbol.Name}'");
|
||||
}
|
||||
|
@ -498,7 +500,8 @@ namespace System.Runtime.CompilerServices
|
|||
// Output the interceptor method signature preceded by the [InterceptsLocation] attribute.
|
||||
var startPosition = operatorSyntax.SyntaxTree.GetLineSpan(memberAccessSyntax.Name.Span, cancellationToken).StartLinePosition;
|
||||
var interceptorName = $"Query{queryNum}_{memberAccessSyntax.Name}{operatorNum}";
|
||||
code.AppendLine($"""[InterceptsLocation(@"{operatorSyntax.SyntaxTree.FilePath.Replace("\"","\"\"")}", {startPosition.Line + 1}, {startPosition.Character + 1})]""");
|
||||
code.AppendLine(
|
||||
$"""[InterceptsLocation(@"{operatorSyntax.SyntaxTree.FilePath.Replace("\"", "\"\"")}", {startPosition.Line + 1}, {startPosition.Character + 1})]""");
|
||||
GenerateInterceptorMethodSignature();
|
||||
code.AppendLine("{").IncrementIndent();
|
||||
|
||||
|
@ -550,8 +553,8 @@ namespace System.Runtime.CompilerServices
|
|||
|| genericDefinition == typeof(IAsyncEnumerable<>));
|
||||
|
||||
var isQueryable = !isAsync
|
||||
&& operatorExpression.Type.IsGenericType
|
||||
&& operatorExpression.Type.GetGenericTypeDefinition() == typeof(IQueryable<>);
|
||||
&& operatorExpression.Type.IsGenericType
|
||||
&& operatorExpression.Type.GetGenericTypeDefinition() == typeof(IQueryable<>);
|
||||
|
||||
var returnValue = isAsync
|
||||
? $"IAsyncEnumerable<{sourceElementTypeName}>"
|
||||
|
@ -583,7 +586,8 @@ namespace System.Runtime.CompilerServices
|
|||
// TODO: This is an additional runtime allocation; if we had System.Linq.Async we wouldn't need this. We could
|
||||
// have additional versions of all async terminating operators over IAsyncEnumerable<T> (effectively duplicating
|
||||
// System.Linq.Async) as an alternative.
|
||||
code.AppendLine($"var asyncQueryingEnumerable = new PrecompiledQueryableAsyncEnumerableAdapter<{sourceElementTypeName}>(queryingEnumerable);");
|
||||
code.AppendLine(
|
||||
$"var asyncQueryingEnumerable = new PrecompiledQueryableAsyncEnumerableAdapter<{sourceElementTypeName}>(queryingEnumerable);");
|
||||
code.Append("return asyncQueryingEnumerable");
|
||||
}
|
||||
else
|
||||
|
@ -636,13 +640,16 @@ namespace System.Runtime.CompilerServices
|
|||
.Append(' ')
|
||||
.Append(interceptorName);
|
||||
|
||||
var (typeParameters, constraints) = (reducedOperatorSymbol.IsGenericMethod, reducedOperatorSymbol.ContainingType.IsGenericType) switch
|
||||
{
|
||||
(true, false) => (reducedOperatorSymbol.TypeParameters, ((MethodDeclarationSyntax)_g.MethodDeclaration(reducedOperatorSymbol)).ConstraintClauses),
|
||||
(false, true) => (reducedOperatorSymbol.ContainingType.TypeParameters, ((TypeDeclarationSyntax)_g.Declaration(reducedOperatorSymbol.ContainingType)).ConstraintClauses),
|
||||
(false, false) => ([], []),
|
||||
(true, true) => throw new NotImplementedException("Generic method on generic type not supported")
|
||||
};
|
||||
var (typeParameters, constraints) =
|
||||
(reducedOperatorSymbol.IsGenericMethod, reducedOperatorSymbol.ContainingType.IsGenericType) switch
|
||||
{
|
||||
(true, false) => (reducedOperatorSymbol.TypeParameters,
|
||||
((MethodDeclarationSyntax)_g.MethodDeclaration(reducedOperatorSymbol)).ConstraintClauses),
|
||||
(false, true) => (reducedOperatorSymbol.ContainingType.TypeParameters,
|
||||
((TypeDeclarationSyntax)_g.Declaration(reducedOperatorSymbol.ContainingType)).ConstraintClauses),
|
||||
(false, false) => ([], []),
|
||||
(true, true) => throw new NotImplementedException("Generic method on generic type not supported")
|
||||
};
|
||||
|
||||
if (typeParameters.Length > 0)
|
||||
{
|
||||
|
@ -774,7 +781,8 @@ namespace System.Runtime.CompilerServices
|
|||
var collectedNamespaces = new HashSet<string>();
|
||||
var unsafeAccessors = new HashSet<MethodDeclarationSyntax>();
|
||||
var roslynPathSegment = _linqToCSharpTranslator.TranslateExpression(
|
||||
linqPathSegment, constantReplacements: null, _memberAccessReplacements, collectedNamespaces, unsafeAccessors);
|
||||
linqPathSegment, constantReplacements: null, _memberAccessReplacements, collectedNamespaces,
|
||||
unsafeAccessors);
|
||||
|
||||
var variableName = capturedVariablesPathTree.ExpressionType.Name;
|
||||
variableName = char.ToLower(variableName[0]) + variableName[1..^"Expression".Length] + ++variableCounter;
|
||||
|
@ -1066,10 +1074,14 @@ namespace System.Runtime.CompilerServices
|
|||
method.GetParameters()[1].ParameterType.GenericTypeArguments[0].GenericTypeArguments[1])),
|
||||
|
||||
// ExecuteDelete/Update behave just like other scalar-returning operators
|
||||
nameof(EntityFrameworkQueryableExtensions.ExecuteDeleteAsync) when method.DeclaringType == typeof(EntityFrameworkQueryableExtensions)
|
||||
=> RewriteToSync(typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteDelete))),
|
||||
nameof(EntityFrameworkQueryableExtensions.ExecuteUpdateAsync) when method.DeclaringType == typeof(EntityFrameworkQueryableExtensions)
|
||||
=> RewriteToSync(typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteUpdate))),
|
||||
nameof(EntityFrameworkQueryableExtensions.ExecuteDeleteAsync) when method.DeclaringType
|
||||
== typeof(EntityFrameworkQueryableExtensions)
|
||||
=> RewriteToSync(
|
||||
typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteDelete))),
|
||||
nameof(EntityFrameworkQueryableExtensions.ExecuteUpdateAsync) when method.DeclaringType
|
||||
== typeof(EntityFrameworkQueryableExtensions)
|
||||
=> RewriteToSync(
|
||||
typeof(EntityFrameworkQueryableExtensions).GetMethod(nameof(EntityFrameworkQueryableExtensions.ExecuteUpdate))),
|
||||
|
||||
// In the regular case (sync terminating operator which needs to stay in the query tree), simply compose the terminating
|
||||
// operator over the penultimate and return that.
|
||||
|
|
|
@ -33,7 +33,6 @@ public class QueryLocator : CSharpSyntaxWalker
|
|||
private List<InvocationExpressionSyntax> _locatedQueries = null!;
|
||||
private List<PrecompiledQueryCodeGenerator.QueryPrecompilationError> _precompilationErrors = null!;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Loads a new <see cref="Compilation" />, representing a user project in which to locate queries.
|
||||
/// </summary>
|
||||
|
@ -55,7 +54,7 @@ public class QueryLocator : CSharpSyntaxWalker
|
|||
/// </summary>
|
||||
/// <param name="syntaxTree">A <see cref="SyntaxTree" /> in which to locate EF LINQ queries.</param>
|
||||
/// <param name="precompilationErrors">
|
||||
/// A list of errors populated with dynamic LINQ queries detected in <paramref name="syntaxTree"/>.
|
||||
/// A list of errors populated with dynamic LINQ queries detected in <paramref name="syntaxTree" />.
|
||||
/// </param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
|
||||
/// <returns>A list of EF LINQ queries confirmed to be compatible with precompilation.</returns>
|
||||
|
@ -82,7 +81,7 @@ public class QueryLocator : CSharpSyntaxWalker
|
|||
|
||||
_cancellationToken = cancellationToken;
|
||||
_semanticModel = _compilation.GetSemanticModel(syntaxTree);
|
||||
_locatedQueries = new();
|
||||
_locatedQueries = new List<InvocationExpressionSyntax>();
|
||||
_precompilationErrors = precompilationErrors;
|
||||
Visit(syntaxTree.GetRoot(cancellationToken));
|
||||
|
||||
|
@ -247,7 +246,8 @@ public class QueryLocator : CSharpSyntaxWalker
|
|||
if (innerExpression is QueryExpressionSyntax or ParenthesizedExpressionSyntax { Expression: QueryExpressionSyntax })
|
||||
{
|
||||
_precompilationErrors.Add(
|
||||
new(query, new InvalidOperationException(DesignStrings.QueryComprehensionSyntaxNotSupportedInPrecompiledQueries)));
|
||||
new PrecompiledQueryCodeGenerator.QueryPrecompilationError(
|
||||
query, new InvalidOperationException(DesignStrings.QueryComprehensionSyntaxNotSupportedInPrecompiledQueries)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,9 @@ public class QueryLocator : CSharpSyntaxWalker
|
|||
return true;
|
||||
}
|
||||
|
||||
_precompilationErrors.Add(new(query, new InvalidOperationException(DesignStrings.DynamicQueryNotSupported)));
|
||||
_precompilationErrors.Add(
|
||||
new PrecompiledQueryCodeGenerator.QueryPrecompilationError(
|
||||
query, new InvalidOperationException(DesignStrings.DynamicQueryNotSupported)));
|
||||
return false;
|
||||
|
||||
bool IsDbContext(ExpressionSyntax expression)
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Editing;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Design.Internal;
|
||||
// ReSharper disable once CheckNamespace
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Query.Internal;
|
||||
|
@ -29,7 +28,8 @@ public class RuntimeModelLinqToCSharpSyntaxTranslator : LinqToCSharpSyntaxTransl
|
|||
/// 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 RuntimeModelLinqToCSharpSyntaxTranslator(SyntaxGenerator syntaxGenerator) : base(syntaxGenerator)
|
||||
public RuntimeModelLinqToCSharpSyntaxTranslator(SyntaxGenerator syntaxGenerator)
|
||||
: base(syntaxGenerator)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,10 @@ public class RuntimeModelLinqToCSharpSyntaxTranslator : LinqToCSharpSyntaxTransl
|
|||
/// 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>
|
||||
protected override void TranslateNonPublicMemberAssignment(MemberExpression memberExpression, Expression value, SyntaxKind assignmentKind)
|
||||
protected override void TranslateNonPublicMemberAssignment(
|
||||
MemberExpression memberExpression,
|
||||
Expression value,
|
||||
SyntaxKind assignmentKind)
|
||||
{
|
||||
var propertyInfo = memberExpression.Member as PropertyInfo;
|
||||
var member = propertyInfo?.SetMethod ?? memberExpression.Member;
|
||||
|
@ -134,15 +137,18 @@ public class RuntimeModelLinqToCSharpSyntaxTranslator : LinqToCSharpSyntaxTransl
|
|||
|
||||
Result = InvocationExpression(
|
||||
IdentifierName(methodName.Name),
|
||||
ArgumentList(SeparatedList(new[]
|
||||
{
|
||||
Argument(Translate<ExpressionSyntax>(memberExpression.Expression)),
|
||||
Argument(Translate<ExpressionSyntax>(value))
|
||||
})));
|
||||
ArgumentList(
|
||||
SeparatedList(
|
||||
new[]
|
||||
{
|
||||
Argument(Translate<ExpressionSyntax>(memberExpression.Expression)),
|
||||
Argument(Translate<ExpressionSyntax>(value))
|
||||
})));
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = AssignmentExpression(assignmentKind,
|
||||
Result = AssignmentExpression(
|
||||
assignmentKind,
|
||||
InvocationExpression(
|
||||
IdentifierName(methodName.Name),
|
||||
ArgumentList(SeparatedList(new[] { Argument(Translate<ExpressionSyntax>(memberExpression.Expression)) }))),
|
||||
|
|
|
@ -80,10 +80,11 @@ public class CSharpModelGenerator : ModelCodeGenerator
|
|||
var resultingFiles = new ScaffoldedModel
|
||||
{
|
||||
ContextFile = new ScaffoldedFile
|
||||
(options.ContextDir != null
|
||||
(
|
||||
options.ContextDir != null
|
||||
? Path.Combine(options.ContextDir, dbContextFileName)
|
||||
: dbContextFileName,
|
||||
generatedCode)
|
||||
generatedCode)
|
||||
};
|
||||
|
||||
foreach (var entityType in model.GetEntityTypes())
|
||||
|
|
|
@ -68,7 +68,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
|
||||
var assemblyAttributesCode = CreateAssemblyAttributes(options.ModelNamespace, options.ContextType, nullable);
|
||||
var assemblyInfoFileName = UniquifyFileName(options.ContextType.ShortDisplayName() + AssemblyAttributesSuffix, options);
|
||||
scaffoldedFiles.Add(new(assemblyInfoFileName, assemblyAttributesCode));
|
||||
scaffoldedFiles.Add(new ScaffoldedFile(assemblyInfoFileName, assemblyAttributesCode));
|
||||
|
||||
var memberAccessReplacements = new Dictionary<MemberInfo, QualifiedName>();
|
||||
if (options.ForNativeAot)
|
||||
|
@ -94,7 +94,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
|
||||
foreach (var unsafeAccessorPair in unsafeAccessorTypes)
|
||||
{
|
||||
(var unsafeAccessorType, var members) = unsafeAccessorPair;
|
||||
var (unsafeAccessorType, members) = unsafeAccessorPair;
|
||||
var generatedCode = GenerateUnsafeAccessorType(
|
||||
unsafeAccessorType,
|
||||
members,
|
||||
|
@ -104,26 +104,27 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
nullable);
|
||||
|
||||
var entityTypeFileName = UniquifyFileName(unsafeAccessorClassNames[unsafeAccessorType], options);
|
||||
scaffoldedFiles.Add(new(entityTypeFileName, generatedCode));
|
||||
scaffoldedFiles.Add(new ScaffoldedFile(entityTypeFileName, generatedCode));
|
||||
}
|
||||
}
|
||||
|
||||
var modelCode = CreateModel(options.ModelNamespace, options.ContextType, nullable);
|
||||
var modelFileName = UniquifyFileName(options.ContextType.ShortDisplayName() + ModelSuffix, options);
|
||||
scaffoldedFiles.Add(new(modelFileName, modelCode));
|
||||
scaffoldedFiles.Add(new ScaffoldedFile(modelFileName, modelCode));
|
||||
|
||||
var configurationClassNames = new Dictionary<ITypeBase, string>();
|
||||
var modelBuilderCode = CreateModelBuilder(
|
||||
model, options.ModelNamespace, options.ContextType, configurationClassNames, nullable, options.ForNativeAot);
|
||||
var modelBuilderFileName = UniquifyFileName(options.ContextType.ShortDisplayName() + ModelBuilderSuffix, options);
|
||||
scaffoldedFiles.Add(new(modelBuilderFileName, modelBuilderCode));
|
||||
scaffoldedFiles.Add(new ScaffoldedFile(modelBuilderFileName, modelBuilderCode));
|
||||
|
||||
foreach (var entityType in model.GetEntityTypesInHierarchicalOrder())
|
||||
{
|
||||
var generatedCode = GenerateEntityType(entityType, options.ModelNamespace, configurationClassNames, memberAccessReplacements, nullable, options.ForNativeAot);
|
||||
var generatedCode = GenerateEntityType(
|
||||
entityType, options.ModelNamespace, configurationClassNames, memberAccessReplacements, nullable, options.ForNativeAot);
|
||||
|
||||
var entityTypeFileName = UniquifyFileName(configurationClassNames[entityType], options);
|
||||
scaffoldedFiles.Add(new(entityTypeFileName, generatedCode));
|
||||
scaffoldedFiles.Add(new ScaffoldedFile(entityTypeFileName, generatedCode));
|
||||
}
|
||||
|
||||
return scaffoldedFiles;
|
||||
|
@ -176,11 +177,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
bool nullable)
|
||||
{
|
||||
var mainBuilder = new IndentedStringBuilder();
|
||||
var namespaces = new SortedSet<string>(new NamespaceComparer())
|
||||
{
|
||||
typeof(DbContextModelAttribute).Namespace!,
|
||||
@namespace
|
||||
};
|
||||
var namespaces = new SortedSet<string>(new NamespaceComparer()) { typeof(DbContextModelAttribute).Namespace!, @namespace };
|
||||
|
||||
AddNamespace(contextType, namespaces);
|
||||
|
||||
|
@ -191,7 +188,8 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
return GenerateHeader(namespaces, currentNamespace: "", nullable) + mainBuilder;
|
||||
}
|
||||
|
||||
private string GetModelClassName(Type contextType) => _code.Identifier(contextType.ShortDisplayName()) + ModelSuffix;
|
||||
private string GetModelClassName(Type contextType)
|
||||
=> _code.Identifier(contextType.ShortDisplayName()) + ModelSuffix;
|
||||
|
||||
private string GenerateUnsafeAccessorType(
|
||||
Type type,
|
||||
|
@ -221,7 +219,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
var genericParameters = type.GetGenericArguments();
|
||||
mainBuilder
|
||||
.Append("<")
|
||||
.AppendJoin(genericParameters.Select(a => _code.Reference(a)), ", ")
|
||||
.AppendJoin(genericParameters.Select(a => _code.Reference(a)))
|
||||
.AppendLine(">");
|
||||
|
||||
using (mainBuilder.Indent())
|
||||
|
@ -229,7 +227,8 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
foreach (var genericParameter in genericParameters)
|
||||
{
|
||||
if (genericParameter.GetGenericParameterConstraints().Length == 0
|
||||
&& (genericParameter.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask) == GenericParameterAttributes.None)
|
||||
&& (genericParameter.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask)
|
||||
== GenericParameterAttributes.None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -256,7 +255,8 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
constraintList.Add("new()");
|
||||
}
|
||||
|
||||
Check.DebugAssert(!constraintAttributes.HasFlag(GenericParameterAttributes.VarianceMask),
|
||||
Check.DebugAssert(
|
||||
!constraintAttributes.HasFlag(GenericParameterAttributes.VarianceMask),
|
||||
"Variance constraints not supported for type: " + type.DisplayName());
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
}
|
||||
|
||||
mainBuilder
|
||||
.AppendJoin(constraintList, ", ")
|
||||
.AppendJoin(constraintList)
|
||||
.AppendLine();
|
||||
}
|
||||
}
|
||||
|
@ -351,7 +351,8 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
.Append("public partial class ").Append(className).AppendLine(" : " + nameof(RuntimeModel))
|
||||
.AppendLine("{")
|
||||
.AppendLine(" private static readonly bool _useOldBehavior31751 =")
|
||||
.AppendLine(@" System.AppContext.TryGetSwitch(""Microsoft.EntityFrameworkCore.Issue31751"", out var enabled31751) && enabled31751;")
|
||||
.AppendLine(
|
||||
@" System.AppContext.TryGetSwitch(""Microsoft.EntityFrameworkCore.Issue31751"", out var enabled31751) && enabled31751;")
|
||||
.AppendLine();
|
||||
|
||||
using (mainBuilder.Indent())
|
||||
|
@ -724,26 +725,36 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
.AppendLine("{");
|
||||
using (mainBuilder.Indent())
|
||||
{
|
||||
CreateEntityType(entityType, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, nullable, nativeAot);
|
||||
CreateEntityType(
|
||||
entityType, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, nullable,
|
||||
nativeAot);
|
||||
|
||||
foreach (var complexProperty in entityType.GetDeclaredComplexProperties())
|
||||
{
|
||||
CreateComplexProperty(complexProperty, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, className, nullable, nativeAot);
|
||||
CreateComplexProperty(
|
||||
complexProperty, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements,
|
||||
className, nullable, nativeAot);
|
||||
}
|
||||
|
||||
var foreignKeyNumber = 1;
|
||||
foreach (var foreignKey in entityType.GetDeclaredForeignKeys())
|
||||
{
|
||||
CreateForeignKey(foreignKey, foreignKeyNumber++, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, className, nullable, nativeAot);
|
||||
CreateForeignKey(
|
||||
foreignKey, foreignKeyNumber++, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames,
|
||||
memberAccessReplacements, className, nullable, nativeAot);
|
||||
}
|
||||
|
||||
var navigationNumber = 1;
|
||||
foreach (var navigation in entityType.GetDeclaredSkipNavigations())
|
||||
{
|
||||
CreateSkipNavigation(navigation, navigationNumber++, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, className, nullable, nativeAot);
|
||||
CreateSkipNavigation(
|
||||
navigation, navigationNumber++, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames,
|
||||
memberAccessReplacements, className, nullable, nativeAot);
|
||||
}
|
||||
|
||||
CreateAnnotations(entityType, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, nullable, nativeAot);
|
||||
CreateAnnotations(
|
||||
entityType, @namespace, mainBuilder, methodBuilder, namespaces, entityClassNames, memberAccessReplacements, nullable,
|
||||
nativeAot);
|
||||
|
||||
var methods = methodBuilder.ToString();
|
||||
if (!string.IsNullOrEmpty(methods))
|
||||
|
@ -1164,7 +1175,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
{
|
||||
AddNamespace(valueComparerType, parameters.Namespaces);
|
||||
|
||||
var valueComparerString = $"new {_code.Reference(valueComparerType)}()" ;
|
||||
var valueComparerString = $"new {_code.Reference(valueComparerType)}()";
|
||||
if (property.ClrType.IsNullableValueType())
|
||||
{
|
||||
var valueComparerElementType = ((ValueComparer)Activator.CreateInstance(valueComparerType)!).Type;
|
||||
|
@ -1254,9 +1265,9 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
|
||||
var providerValueComparer = property.GetProviderValueComparer();
|
||||
var defaultProviderValueComparer = property.ClrType.UnwrapNullableType()
|
||||
== (property.GetTypeMapping().Converter?.ProviderClrType ?? property.ClrType).UnwrapNullableType()
|
||||
? property.GetKeyValueComparer()
|
||||
: property.GetTypeMapping().ProviderValueComparer;
|
||||
== (property.GetTypeMapping().Converter?.ProviderClrType ?? property.ClrType).UnwrapNullableType()
|
||||
? property.GetKeyValueComparer()
|
||||
: property.GetTypeMapping().ProviderValueComparer;
|
||||
if (providerValueComparerType == null
|
||||
&& providerValueComparer != defaultProviderValueComparer)
|
||||
{
|
||||
|
@ -1264,7 +1275,8 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
.Append(variableName)
|
||||
.Append(".SetProviderValueComparer(");
|
||||
CreateValueComparer(
|
||||
providerValueComparer, property.GetTypeMapping().ProviderValueComparer, nameof(CoreTypeMapping.ProviderValueComparer), propertyParameters);
|
||||
providerValueComparer, property.GetTypeMapping().ProviderValueComparer, nameof(CoreTypeMapping.ProviderValueComparer),
|
||||
propertyParameters);
|
||||
|
||||
mainBuilder
|
||||
.AppendLine(");");
|
||||
|
@ -1330,9 +1342,9 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
|
||||
private void
|
||||
SetPropertyBaseProperties(
|
||||
IPropertyBase property,
|
||||
Dictionary<MemberInfo, QualifiedName>? memberAccessReplacements,
|
||||
CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
|
||||
IPropertyBase property,
|
||||
Dictionary<MemberInfo, QualifiedName>? memberAccessReplacements,
|
||||
CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
|
||||
{
|
||||
if (!parameters.ForNativeAot)
|
||||
{
|
||||
|
@ -1356,13 +1368,25 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(variableName).AppendLine(".SetGetter(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(getterExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
getterExpression, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(_code.Expression(hasSentinelExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
hasSentinelExpression, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(_code.Expression(structuralGetterExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
structuralGetterExpression, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(_code.Expression(hasStructuralSentinelExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
hasStructuralSentinelExpression, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
|
@ -1371,7 +1395,10 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(variableName).AppendLine(".SetSetter(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(setterExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
setterExpression, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
|
@ -1380,14 +1407,18 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(variableName).AppendLine(".SetMaterializationSetter(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(materializationSetterExpression, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
materializationSetterExpression, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
}
|
||||
|
||||
if (property is not IServiceProperty)
|
||||
{
|
||||
PropertyAccessorsFactory.Instance.Create(property,
|
||||
PropertyAccessorsFactory.Instance.Create(
|
||||
property,
|
||||
out var currentValueGetter,
|
||||
out var preStoreGeneratedCurrentValueGetter,
|
||||
out var originalValueGetter,
|
||||
|
@ -1397,24 +1428,41 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(variableName).AppendLine(".SetAccessors(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(currentValueGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
currentValueGetter, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(_code.Expression(preStoreGeneratedCurrentValueGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
preStoreGeneratedCurrentValueGetter, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(originalValueGetter == null
|
||||
? "null"
|
||||
: _code.Expression(originalValueGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
originalValueGetter == null
|
||||
? "null"
|
||||
: _code.Expression(
|
||||
originalValueGetter, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements),
|
||||
skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(_code.Expression(relationshipSnapshotGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
relationshipSnapshotGetter, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(valueBufferGetter == null
|
||||
? "null"
|
||||
: _code.Expression(valueBufferGetter, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
valueBufferGetter == null
|
||||
? "null"
|
||||
: _code.Expression(
|
||||
valueBufferGetter, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements),
|
||||
skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
Check.DebugAssert(unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " +
|
||||
string.Join(Environment.NewLine, unsafeAccessors));
|
||||
Check.DebugAssert(
|
||||
unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + string.Join(Environment.NewLine, unsafeAccessors));
|
||||
}
|
||||
|
||||
var propertyIndexes = ((IRuntimePropertyBase)property).PropertyIndexes;
|
||||
|
@ -1428,6 +1476,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
.Append("storeGenerationIndex: ").Append(_code.Literal(propertyIndexes.StoreGenerationIndex)).AppendLine(");")
|
||||
.DecrementIndent();
|
||||
}
|
||||
|
||||
private void RegisterPrivateAccessors(
|
||||
ITypeBase structuralType,
|
||||
CompiledModelCodeGenerationOptions options,
|
||||
|
@ -1465,13 +1514,17 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
}
|
||||
|
||||
var getter = RegisterPrivateAccessor(
|
||||
property, forMaterialization: false, forSet: false, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, ref memberAccessReplacements);
|
||||
property, forMaterialization: false, forSet: false, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes,
|
||||
ref memberAccessReplacements);
|
||||
var setter = RegisterPrivateAccessor(
|
||||
property, forMaterialization: false, forSet: true, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, ref memberAccessReplacements);
|
||||
property, forMaterialization: false, forSet: true, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes,
|
||||
ref memberAccessReplacements);
|
||||
var queryGetter = RegisterPrivateAccessor(
|
||||
property, forMaterialization: true, forSet: false, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, ref memberAccessReplacements);
|
||||
property, forMaterialization: true, forSet: false, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes,
|
||||
ref memberAccessReplacements);
|
||||
var querySetter = RegisterPrivateAccessor(
|
||||
property, forMaterialization: true, forSet: true, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes, ref memberAccessReplacements);
|
||||
property, forMaterialization: true, forSet: true, @namespace, unsafeAccessorClassNames, unsafeAccessorTypes,
|
||||
ref memberAccessReplacements);
|
||||
|
||||
if (getter != null
|
||||
|| setter != null
|
||||
|
@ -1552,7 +1605,8 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
if (!unsafeAccessorClassNames.TryGetValue(declaringType, out var className))
|
||||
{
|
||||
className = Uniquifier.Uniquify(
|
||||
declaringType.Name[..declaringType.Name.IndexOf('`')], unsafeAccessorClassNames.Inverse, UnsafeAccessorsSuffix, int.MaxValue);
|
||||
declaringType.Name[..declaringType.Name.IndexOf('`')], unsafeAccessorClassNames.Inverse, UnsafeAccessorsSuffix,
|
||||
int.MaxValue);
|
||||
unsafeAccessorClassNames[declaringType] = className;
|
||||
}
|
||||
|
||||
|
@ -1620,8 +1674,9 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
if (methodInfo.GetParameters().Length > 0)
|
||||
{
|
||||
parameters.MainBuilder
|
||||
.Append($", ")
|
||||
.AppendJoin(methodInfo.GetParameters().Select(p => _code.Reference(p.ParameterType) + " " + _code.Identifier(p.Name!)), ", ");
|
||||
.Append(", ")
|
||||
.AppendJoin(
|
||||
methodInfo.GetParameters().Select(p => _code.Reference(p.ParameterType) + " " + _code.Identifier(p.Name!)));
|
||||
}
|
||||
|
||||
parameters.MainBuilder.AppendLine(");");
|
||||
|
@ -1639,7 +1694,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
return annotation != null
|
||||
? (Type?)annotation.Value
|
||||
: ((Property)property).GetConversion(throwOnProviderClrTypeConflict: false, throwOnValueConverterConflict: false)
|
||||
.ValueConverterType;
|
||||
.ValueConverterType;
|
||||
}
|
||||
|
||||
private void GeneratePropertyBaseParameters(
|
||||
|
@ -2083,8 +2138,12 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
var scopeVariables = new BidirectionalDictionary<object, string>
|
||||
{
|
||||
{ foreignKey.DeclaringEntityType, declaringEntityType },
|
||||
{ foreignKey.DeclaringEntityType != foreignKey.PrincipalEntityType
|
||||
? foreignKey.PrincipalEntityType : new object(), principalEntityType },
|
||||
{
|
||||
foreignKey.DeclaringEntityType != foreignKey.PrincipalEntityType
|
||||
? foreignKey.PrincipalEntityType
|
||||
: new object(),
|
||||
principalEntityType
|
||||
},
|
||||
{ foreignKey, foreignKeyVariable }
|
||||
};
|
||||
|
||||
|
@ -2257,32 +2316,48 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
AddNamespace(propertyType, parameters.Namespaces);
|
||||
mainBuilder
|
||||
.Append(parameters.TargetName)
|
||||
.AppendLine($".SetCollectionAccessor<{_code.Reference(entityType)}, {_code.Reference(propertyType)}, {_code.Reference(elementType)}>(")
|
||||
.AppendLine(
|
||||
$".SetCollectionAccessor<{_code.Reference(entityType)}, {_code.Reference(propertyType)}, {_code.Reference(elementType)}>(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(getCollection == null
|
||||
? "null"
|
||||
: _code.Expression(getCollection, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
getCollection == null
|
||||
? "null"
|
||||
: _code.Expression(
|
||||
getCollection, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(setCollection == null
|
||||
? "null"
|
||||
: _code.Expression(setCollection, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
setCollection == null
|
||||
? "null"
|
||||
: _code.Expression(
|
||||
setCollection, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(setCollectionForMaterialization == null
|
||||
? "null"
|
||||
: _code.Expression(setCollectionForMaterialization, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
setCollectionForMaterialization == null
|
||||
? "null"
|
||||
: _code.Expression(
|
||||
setCollectionForMaterialization, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(createAndSetCollection == null
|
||||
? "null"
|
||||
: _code.Expression(createAndSetCollection, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
createAndSetCollection == null
|
||||
? "null"
|
||||
: _code.Expression(
|
||||
createAndSetCollection, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(",")
|
||||
.AppendLines(createCollection == null
|
||||
? "null"
|
||||
: _code.Expression(createCollection, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
createCollection == null
|
||||
? "null"
|
||||
: _code.Expression(
|
||||
createCollection, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
Check.DebugAssert(unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " +
|
||||
string.Join(Environment.NewLine, unsafeAccessors));
|
||||
Check.DebugAssert(
|
||||
unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " + string.Join(Environment.NewLine, unsafeAccessors));
|
||||
}
|
||||
|
||||
private void CreateSkipNavigation(
|
||||
|
@ -2461,17 +2536,17 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
var scopeVariables = new BidirectionalDictionary<object, string> { { entityType, entityTypeVariable } };
|
||||
|
||||
var parameters = new CSharpRuntimeAnnotationCodeGeneratorParameters(
|
||||
entityTypeVariable,
|
||||
className,
|
||||
@namespace,
|
||||
mainBuilder,
|
||||
methodBuilder,
|
||||
namespaces,
|
||||
scopeVariables.Inverse,
|
||||
scopeVariables,
|
||||
configurationClassNames,
|
||||
nullable,
|
||||
nativeAot);
|
||||
entityTypeVariable,
|
||||
className,
|
||||
@namespace,
|
||||
mainBuilder,
|
||||
methodBuilder,
|
||||
namespaces,
|
||||
scopeVariables.Inverse,
|
||||
scopeVariables,
|
||||
configurationClassNames,
|
||||
nullable,
|
||||
nativeAot);
|
||||
|
||||
if (parameters.ForNativeAot)
|
||||
{
|
||||
|
@ -2492,6 +2567,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
{
|
||||
mainBuilder.Append("!");
|
||||
}
|
||||
|
||||
mainBuilder.AppendLine(";");
|
||||
}
|
||||
|
||||
|
@ -2522,7 +2598,8 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
|
||||
mainBuilder
|
||||
.Append($"{keyVariableName}.{nameof(RuntimeKey.SetPrincipalKeyValueFactory)}(")
|
||||
.AppendLine($"{_code.Reference(typeof(KeyValueFactoryFactory))}.{createKeyValueFactoryMethod}({keyVariableName}));");
|
||||
.AppendLine(
|
||||
$"{_code.Reference(typeof(KeyValueFactoryFactory))}.{createKeyValueFactoryMethod}({keyVariableName}));");
|
||||
|
||||
mainBuilder
|
||||
.Append($"{keyVariableName}.{nameof(RuntimeKey.SetIdentityMapFactory)}(")
|
||||
|
@ -2541,6 +2618,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
{
|
||||
mainBuilder.Append("!");
|
||||
}
|
||||
|
||||
mainBuilder.AppendLine(";");
|
||||
}
|
||||
|
||||
|
@ -2551,7 +2629,11 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(parameters.TargetName).AppendLine(".SetOriginalValuesFactory(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(originalValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
originalValuesFactory, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements),
|
||||
skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
|
@ -2559,7 +2641,11 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(parameters.TargetName).AppendLine(".SetStoreGeneratedValuesFactory(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(storeGeneratedValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
storeGeneratedValuesFactory, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements),
|
||||
skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
|
@ -2567,7 +2653,11 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(parameters.TargetName).AppendLine(".SetTemporaryValuesFactory(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(temporaryValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
temporaryValuesFactory, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements),
|
||||
skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
|
@ -2575,7 +2665,11 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(parameters.TargetName).AppendLine(".SetShadowValuesFactory(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(shadowValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
shadowValuesFactory, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements),
|
||||
skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
|
@ -2583,7 +2677,11 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(parameters.TargetName).AppendLine(".SetEmptyShadowValuesFactory(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(emptyShadowValuesFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
emptyShadowValuesFactory, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements),
|
||||
skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
|
@ -2591,7 +2689,11 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
mainBuilder
|
||||
.Append(parameters.TargetName).AppendLine(".SetRelationshipSnapshotFactory(")
|
||||
.IncrementIndent()
|
||||
.AppendLines(_code.Expression(relationshipSnapshotFactory, parameters.Namespaces, unsafeAccessors, (IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements), skipFinalNewline: true)
|
||||
.AppendLines(
|
||||
_code.Expression(
|
||||
relationshipSnapshotFactory, parameters.Namespaces, unsafeAccessors,
|
||||
(IReadOnlyDictionary<object, string>)parameters.ScopeVariables, memberAccessReplacements),
|
||||
skipFinalNewline: true)
|
||||
.AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
|
@ -2609,8 +2711,9 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
.Append("storeGeneratedCount: ").Append(_code.Literal(counts.StoreGeneratedCount)).AppendLine(");")
|
||||
.DecrementIndent();
|
||||
|
||||
Check.DebugAssert(unsafeAccessors.Count == 0, "Generated unsafe accessors not handled: " +
|
||||
string.Join(Environment.NewLine, unsafeAccessors));
|
||||
Check.DebugAssert(
|
||||
unsafeAccessors.Count == 0,
|
||||
"Generated unsafe accessors not handled: " + string.Join(Environment.NewLine, unsafeAccessors));
|
||||
}
|
||||
|
||||
CreateAnnotations(entityType, _annotationCodeGenerator.Generate, parameters);
|
||||
|
@ -2641,6 +2744,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
{
|
||||
mainBuilder.Append("!");
|
||||
}
|
||||
|
||||
mainBuilder.AppendLine(";");
|
||||
}
|
||||
|
||||
|
@ -2655,6 +2759,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
{
|
||||
mainBuilder.Append("!");
|
||||
}
|
||||
|
||||
mainBuilder.AppendLine(";");
|
||||
|
||||
var typeVariableName = _code.Identifier(
|
||||
|
@ -2683,8 +2788,7 @@ public class CSharpRuntimeModelCodeGenerator : ICompiledModelCodeGenerator
|
|||
annotatable,
|
||||
parameters with
|
||||
{
|
||||
Annotations = annotatable.GetRuntimeAnnotations().ToDictionary(a => a.Name, a => a.Value),
|
||||
IsRuntime = true
|
||||
Annotations = annotatable.GetRuntimeAnnotations().ToDictionary(a => a.Name, a => a.Value), IsRuntime = true
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public class CSharpUniqueNamer<T> : CSharpNamer<T>
|
|||
bool caseSensitive)
|
||||
: base(nameGetter, cSharpUtilities, singularizePluralizer)
|
||||
{
|
||||
_usedNames = new(caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);
|
||||
_usedNames = new HashSet<string>(caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);
|
||||
if (usedNames != null)
|
||||
{
|
||||
foreach (var name in usedNames)
|
||||
|
|
|
@ -179,7 +179,7 @@ public class TextTemplatingModelGenerator : TemplatedModelGenerator
|
|||
|
||||
var entityTypeFileName = entityType.Name + entityTypeExtension;
|
||||
resultingFiles.AdditionalFiles.Add(
|
||||
new ScaffoldedFile(entityTypeFileName, generatedCode));
|
||||
new ScaffoldedFile(entityTypeFileName, generatedCode));
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -72,7 +72,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
{
|
||||
parameters.Namespaces.Add(typeof(Dictionary<,>).Namespace!);
|
||||
parameters.Namespaces.Add(typeof(BindingFlags).Namespace!);
|
||||
var functionsVariable = Dependencies.CSharpHelper.Identifier("functions", functions, parameters.ScopeObjects, capitalize: false);
|
||||
var functionsVariable = Dependencies.CSharpHelper.Identifier(
|
||||
"functions", functions, parameters.ScopeObjects, capitalize: false);
|
||||
parameters.MainBuilder
|
||||
.Append("var ").Append(functionsVariable).AppendLine(" = new Dictionary<string, IDbFunction>();");
|
||||
|
||||
|
@ -89,7 +90,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
out IReadOnlyDictionary<(string, string?), ISequence> sequences))
|
||||
{
|
||||
parameters.Namespaces.Add(typeof(Dictionary<,>).Namespace!);
|
||||
var sequencesVariable = Dependencies.CSharpHelper.Identifier("sequences", sequences, parameters.ScopeObjects, capitalize: false);
|
||||
var sequencesVariable = Dependencies.CSharpHelper.Identifier(
|
||||
"sequences", sequences, parameters.ScopeObjects, capitalize: false);
|
||||
var mainBuilder = parameters.MainBuilder;
|
||||
mainBuilder.Append("var ").Append(sequencesVariable).Append(" = new Dictionary<(string, string");
|
||||
|
||||
|
@ -193,7 +195,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
var defaultMappings = typeBase.GetDefaultMappings();
|
||||
if (defaultMappings.Any())
|
||||
{
|
||||
var tableMappingsVariable = code.Identifier("defaultTableMappings", defaultMappings, parameters.ScopeObjects, capitalize: false);
|
||||
var tableMappingsVariable = code.Identifier(
|
||||
"defaultTableMappings", defaultMappings, parameters.ScopeObjects, capitalize: false);
|
||||
mainBuilder
|
||||
.AppendLine()
|
||||
.AppendLine($"var {tableMappingsVariable} = new List<TableMappingBase<ColumnMappingBase>>();")
|
||||
|
@ -238,7 +241,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
var sqlQueryMappings = typeBase.GetSqlQueryMappings();
|
||||
if (sqlQueryMappings.Any())
|
||||
{
|
||||
var sqlQueryMappingsVariable = code.Identifier("sqlQueryMappings", sqlQueryMappings, parameters.ScopeObjects, capitalize: false);
|
||||
var sqlQueryMappingsVariable = code.Identifier(
|
||||
"sqlQueryMappings", sqlQueryMappings, parameters.ScopeObjects, capitalize: false);
|
||||
mainBuilder
|
||||
.AppendLine()
|
||||
.AppendLine($"var {sqlQueryMappingsVariable} = new List<SqlQueryMapping>();")
|
||||
|
@ -253,7 +257,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
var functionMappings = typeBase.GetFunctionMappings();
|
||||
if (functionMappings.Any())
|
||||
{
|
||||
var functionMappingsVariable = code.Identifier("functionMappings", functionMappings, parameters.ScopeObjects, capitalize: false);
|
||||
var functionMappingsVariable = code.Identifier(
|
||||
"functionMappings", functionMappings, parameters.ScopeObjects, capitalize: false);
|
||||
mainBuilder
|
||||
.AppendLine()
|
||||
.AppendLine($"var {functionMappingsVariable} = new List<FunctionMapping>();")
|
||||
|
@ -261,14 +266,15 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
.AppendLine($"{code.Literal(RelationalAnnotationNames.FunctionMappings)}, {functionMappingsVariable});");
|
||||
foreach (var mapping in functionMappings)
|
||||
{
|
||||
Create(mapping, functionMappingsVariable, parameters);
|
||||
Create(mapping, functionMappingsVariable, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
var deleteStoredProcedureMappings = typeBase.GetDeleteStoredProcedureMappings();
|
||||
if (deleteStoredProcedureMappings.Any())
|
||||
{
|
||||
var deleteSprocMappingsVariable = code.Identifier("deleteSprocMappings", deleteStoredProcedureMappings, parameters.ScopeObjects, capitalize: false);
|
||||
var deleteSprocMappingsVariable = code.Identifier(
|
||||
"deleteSprocMappings", deleteStoredProcedureMappings, parameters.ScopeObjects, capitalize: false);
|
||||
mainBuilder
|
||||
.AppendLine()
|
||||
.AppendLine($"var {deleteSprocMappingsVariable} = new List<StoredProcedureMapping>();")
|
||||
|
@ -288,7 +294,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
var insertStoredProcedureMappings = typeBase.GetInsertStoredProcedureMappings();
|
||||
if (typeBase.GetInsertStoredProcedureMappings().Any())
|
||||
{
|
||||
var insertSprocMappingsVariable = code.Identifier("insertSprocMappings", insertStoredProcedureMappings, parameters.ScopeObjects, capitalize: false);
|
||||
var insertSprocMappingsVariable = code.Identifier(
|
||||
"insertSprocMappings", insertStoredProcedureMappings, parameters.ScopeObjects, capitalize: false);
|
||||
mainBuilder
|
||||
.AppendLine()
|
||||
.AppendLine($"var {insertSprocMappingsVariable} = new List<StoredProcedureMapping>();")
|
||||
|
@ -308,7 +315,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
var updateStoredProcedureMappings = typeBase.GetUpdateStoredProcedureMappings();
|
||||
if (updateStoredProcedureMappings.Any())
|
||||
{
|
||||
var updateSprocMappingsVariable = code.Identifier("updateSprocMappings", updateStoredProcedureMappings, parameters.ScopeObjects, capitalize: false);
|
||||
var updateSprocMappingsVariable = code.Identifier(
|
||||
"updateSprocMappings", updateStoredProcedureMappings, parameters.ScopeObjects, capitalize: false);
|
||||
mainBuilder
|
||||
.AppendLine()
|
||||
.AppendLine($"var {updateSprocMappingsVariable} = new List<StoredProcedureMapping>();")
|
||||
|
@ -535,7 +543,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
|
||||
foreach (var parameter in function.Parameters)
|
||||
{
|
||||
var parameterVariable = code.Identifier(parameter.Name + "FunctionParameter", parameter, parameters.ScopeObjects, capitalize: false);
|
||||
var parameterVariable = code.Identifier(
|
||||
parameter.Name + "FunctionParameter", parameter, parameters.ScopeObjects, capitalize: false);
|
||||
mainBuilder.AppendLine($"var {parameterVariable} = {functionVariable}.FindParameter({code.Literal(parameter.Name)})!;");
|
||||
|
||||
CreateAnnotations(
|
||||
|
@ -601,7 +610,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
}
|
||||
|
||||
var code = Dependencies.CSharpHelper;
|
||||
storedProcedureVariable = code.Identifier(storeStoredProcedure.Name + "StoreSproc", storeStoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
storedProcedureVariable = code.Identifier(
|
||||
storeStoredProcedure.Name + "StoreSproc", storeStoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
var mainBuilder = parameters.MainBuilder;
|
||||
mainBuilder
|
||||
.Append($"var {storedProcedureVariable} = new StoreStoredProcedure(")
|
||||
|
@ -946,6 +956,7 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
mainBuilder
|
||||
.Append($"new CompositeRowKeyValueFactory({uniqueConstraintVariable})");
|
||||
}
|
||||
|
||||
mainBuilder.AppendLine(");");
|
||||
|
||||
CreateAnnotations(
|
||||
|
@ -1012,6 +1023,7 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
mainBuilder
|
||||
.Append($"new CompositeRowIndexValueFactory({indexVariable})");
|
||||
}
|
||||
|
||||
mainBuilder.AppendLine(");");
|
||||
|
||||
CreateAnnotations(
|
||||
|
@ -1097,7 +1109,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
{
|
||||
if (!parameters.ScopeVariables.TryGetValue(mappedForeignKey, out var foreignKeyVariable))
|
||||
{
|
||||
foreignKeyVariable = code.Identifier(foreignKeyConstraintVariable + "Fk", mappedForeignKey, parameters.ScopeObjects, capitalize: false);
|
||||
foreignKeyVariable = code.Identifier(
|
||||
foreignKeyConstraintVariable + "Fk", mappedForeignKey, parameters.ScopeObjects, capitalize: false);
|
||||
|
||||
mainBuilder
|
||||
.AppendLine($"var {foreignKeyVariable} = RelationalModel.GetForeignKey(this,").IncrementIndent()
|
||||
|
@ -1306,7 +1319,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
|
||||
var sqlQuery = sqlQueryMapping.SqlQuery;
|
||||
var sqlQueryVariable = GetOrCreate(sqlQuery, parameters);
|
||||
var sqlQueryMappingVariable = code.Identifier(sqlQuery.Name + "SqlQueryMapping", sqlQueryMapping, parameters.ScopeObjects, capitalize: false);
|
||||
var sqlQueryMappingVariable = code.Identifier(
|
||||
sqlQuery.Name + "SqlQueryMapping", sqlQueryMapping, parameters.ScopeObjects, capitalize: false);
|
||||
|
||||
GenerateAddMapping(
|
||||
sqlQueryMapping,
|
||||
|
@ -1359,7 +1373,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
var storeFunction = functionMapping.StoreFunction;
|
||||
var functionVariable = GetOrCreate(storeFunction, parameters);
|
||||
var dbFunctionVariable = metadataVariables[functionMapping.DbFunction];
|
||||
var functionMappingVariable = code.Identifier(storeFunction.Name + "FunctionMapping", functionMapping, parameters.ScopeObjects, capitalize: false);
|
||||
var functionMappingVariable = code.Identifier(
|
||||
storeFunction.Name + "FunctionMapping", functionMapping, parameters.ScopeObjects, capitalize: false);
|
||||
|
||||
GenerateAddMapping(
|
||||
functionMapping,
|
||||
|
@ -1425,11 +1440,13 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
if (!metadataVariables.TryGetValue(sprocMapping.StoredProcedure, out var sprocVariable))
|
||||
{
|
||||
var sprocSnippet = CreateFindSnippet(sprocMapping.StoredProcedure, metadataVariables);
|
||||
sprocVariable = code.Identifier(storeSproc.Name + sprocMappingType[0] + "Sproc", sprocMapping.StoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
sprocVariable = code.Identifier(
|
||||
storeSproc.Name + sprocMappingType[0] + "Sproc", sprocMapping.StoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
mainBuilder.AppendLine($"var {sprocVariable} = {sprocSnippet};");
|
||||
}
|
||||
|
||||
var sprocMappingVariable = code.Identifier(storeSproc.Name + "SprocMapping", sprocMapping, parameters.ScopeObjects, capitalize: false);
|
||||
var sprocMappingVariable = code.Identifier(
|
||||
storeSproc.Name + "SprocMapping", sprocMapping, parameters.ScopeObjects, capitalize: false);
|
||||
var tableMappingVariable = sprocMapping.TableMapping != null ? metadataVariables[sprocMapping.TableMapping] : null;
|
||||
|
||||
GenerateAddMapping(
|
||||
|
@ -1804,7 +1821,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
{
|
||||
AddNamespace(typeof(StoreObjectDictionary<RuntimeEntityTypeMappingFragment>), parameters.Namespaces);
|
||||
AddNamespace(typeof(StoreObjectIdentifier), parameters.Namespaces);
|
||||
var fragmentsVariable = Dependencies.CSharpHelper.Identifier("fragments", fragments, parameters.ScopeObjects, capitalize: false);
|
||||
var fragmentsVariable = Dependencies.CSharpHelper.Identifier(
|
||||
"fragments", fragments, parameters.ScopeObjects, capitalize: false);
|
||||
parameters.MainBuilder
|
||||
.Append("var ").Append(fragmentsVariable)
|
||||
.AppendLine(" = new StoreObjectDictionary<RuntimeEntityTypeMappingFragment>();");
|
||||
|
@ -1821,7 +1839,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
RelationalAnnotationNames.InsertStoredProcedure,
|
||||
out StoredProcedure insertStoredProcedure))
|
||||
{
|
||||
var sprocVariable = Dependencies.CSharpHelper.Identifier("insertSproc", insertStoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
var sprocVariable = Dependencies.CSharpHelper.Identifier(
|
||||
"insertSproc", insertStoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
|
||||
Create(insertStoredProcedure, sprocVariable, parameters);
|
||||
|
||||
|
@ -1833,7 +1852,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
RelationalAnnotationNames.DeleteStoredProcedure,
|
||||
out StoredProcedure deleteStoredProcedure))
|
||||
{
|
||||
var sprocVariable = Dependencies.CSharpHelper.Identifier("deleteSproc", deleteStoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
var sprocVariable = Dependencies.CSharpHelper.Identifier(
|
||||
"deleteSproc", deleteStoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
|
||||
Create(deleteStoredProcedure, sprocVariable, parameters);
|
||||
|
||||
|
@ -1845,7 +1865,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
RelationalAnnotationNames.UpdateStoredProcedure,
|
||||
out StoredProcedure updateStoredProcedure))
|
||||
{
|
||||
var sprocVariable = Dependencies.CSharpHelper.Identifier("updateSproc", updateStoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
var sprocVariable = Dependencies.CSharpHelper.Identifier(
|
||||
"updateSproc", updateStoredProcedure, parameters.ScopeObjects, capitalize: false);
|
||||
|
||||
Create(updateStoredProcedure, sprocVariable, parameters);
|
||||
|
||||
|
@ -1970,7 +1991,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
{
|
||||
var code = Dependencies.CSharpHelper;
|
||||
var mainBuilder = parameters.MainBuilder;
|
||||
var parameterVariable = code.Identifier(parameter.PropertyName ?? parameter.Name, parameter, parameters.ScopeObjects, capitalize: false);
|
||||
var parameterVariable = code.Identifier(
|
||||
parameter.PropertyName ?? parameter.Name, parameter, parameters.ScopeObjects, capitalize: false);
|
||||
|
||||
mainBuilder
|
||||
.Append("var ").Append(parameterVariable).Append(" = ")
|
||||
|
@ -2061,7 +2083,8 @@ public class RelationalCSharpRuntimeAnnotationCodeGenerator : CSharpRuntimeAnnot
|
|||
{
|
||||
AddNamespace(typeof(StoreObjectDictionary<RuntimeRelationalPropertyOverrides>), parameters.Namespaces);
|
||||
AddNamespace(typeof(StoreObjectIdentifier), parameters.Namespaces);
|
||||
var overridesVariable = Dependencies.CSharpHelper.Identifier("overrides", tableOverrides, parameters.ScopeObjects, capitalize: false);
|
||||
var overridesVariable = Dependencies.CSharpHelper.Identifier(
|
||||
"overrides", tableOverrides, parameters.ScopeObjects, capitalize: false);
|
||||
parameters.MainBuilder.AppendLine()
|
||||
.Append("var ").Append(overridesVariable)
|
||||
.AppendLine(" = new StoreObjectDictionary<RuntimeRelationalPropertyOverrides>();");
|
||||
|
|
|
@ -748,7 +748,8 @@ public static class RelationalEventId
|
|||
/// This event uses the <see cref="MigrationCommandEventData" /> payload when used with a <see cref="DiagnosticSource" />.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static readonly EventId NonTransactionalMigrationOperationWarning = MakeMigrationsId(Id.NonTransactionalMigrationOperationWarning);
|
||||
public static readonly EventId NonTransactionalMigrationOperationWarning =
|
||||
MakeMigrationsId(Id.NonTransactionalMigrationOperationWarning);
|
||||
|
||||
/// <summary>
|
||||
/// A migration lock is being acquired.
|
||||
|
@ -762,7 +763,7 @@ public static class RelationalEventId
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static readonly EventId AcquiringMigrationLock = MakeMigrationsId(Id.AcquiringMigrationLock);
|
||||
|
||||
|
||||
private static readonly string _queryPrefix = DbLoggerCategory.Query.Name + ".";
|
||||
|
||||
private static EventId MakeQueryId(Id id)
|
||||
|
|
|
@ -2365,6 +2365,7 @@ public static class RelationalLoggerExtensions
|
|||
{
|
||||
commandText = commandText.Substring(0, 100) + "...";
|
||||
}
|
||||
|
||||
definition.Log(diagnostics, commandText, migration.GetType().ShortDisplayName());
|
||||
}
|
||||
|
||||
|
@ -2390,6 +2391,7 @@ public static class RelationalLoggerExtensions
|
|||
{
|
||||
commandText = commandText.Substring(0, 100) + "...";
|
||||
}
|
||||
|
||||
return d.GenerateMessage(commandText, p.Migration.GetType().ShortDisplayName());
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Microsoft.EntityFrameworkCore.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
@ -18,5 +19,6 @@ public static class RelationalModelExtensions
|
|||
/// 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 static void EnsureRelationalModel(this IModel model) => model.GetRelationalModel();
|
||||
public static void EnsureRelationalModel(this IModel model)
|
||||
=> model.GetRelationalModel();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
|
@ -139,8 +138,8 @@ public static class RelationalForeignKeyExtensions
|
|||
{
|
||||
foreignKey.DeclaringEntityType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IForeignKeyConstraint>?)foreignKey.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.ForeignKeyMappings)
|
||||
?? Enumerable.Empty<IForeignKeyConstraint>();
|
||||
RelationalAnnotationNames.ForeignKeyMappings)
|
||||
?? Enumerable.Empty<IForeignKeyConstraint>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
@ -170,8 +169,8 @@ public static class RelationalIndexExtensions
|
|||
{
|
||||
index.DeclaringEntityType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<ITableIndex>?)index.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.TableIndexMappings)
|
||||
?? Enumerable.Empty<ITableIndex>();
|
||||
RelationalAnnotationNames.TableIndexMappings)
|
||||
?? Enumerable.Empty<ITableIndex>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
@ -111,8 +110,8 @@ public static class RelationalKeyExtensions
|
|||
{
|
||||
key.DeclaringEntityType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IUniqueConstraint>?)key.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.UniqueConstraintMappings)
|
||||
?? Enumerable.Empty<IUniqueConstraint>();
|
||||
RelationalAnnotationNames.UniqueConstraintMappings)
|
||||
?? Enumerable.Empty<IUniqueConstraint>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -70,7 +70,7 @@ public static class RelationalModelExtensions
|
|||
if (relationalModel == null)
|
||||
{
|
||||
var relationalModelFactory = (Func<IRelationalModel>?)model.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.RelationalModelFactory)
|
||||
RelationalAnnotationNames.RelationalModelFactory)
|
||||
?? throw new InvalidOperationException(CoreStrings.ModelNotFinalized(nameof(GetRelationalModel)));
|
||||
lock (relationalModelFactory)
|
||||
{
|
||||
|
|
|
@ -88,7 +88,7 @@ public static class RelationalOwnedNavigationBuilderExtensions
|
|||
/// only when mapping the column to a database document type.
|
||||
/// </remarks>
|
||||
/// <param name="builder">The builder for the owned navigation being configured.</param>
|
||||
/// <param name="columnType">The database type for the column, or <see langword="null"/> to use the database default.</param>
|
||||
/// <param name="columnType">The database type for the column, or <see langword="null" /> to use the database default.</param>
|
||||
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
|
||||
public static OwnedNavigationBuilder<TOwnerEntity, TDependentEntity> HasColumnType<TOwnerEntity, TDependentEntity>(
|
||||
this OwnedNavigationBuilder<TOwnerEntity, TDependentEntity> builder,
|
||||
|
@ -105,7 +105,7 @@ public static class RelationalOwnedNavigationBuilderExtensions
|
|||
/// only when mapping the column to a database document type.
|
||||
/// </remarks>
|
||||
/// <param name="builder">The builder for the owned navigation being configured.</param>
|
||||
/// <param name="columnType">The database type for the column, or <see langword="null"/> to use the database default.</param>
|
||||
/// <param name="columnType">The database type for the column, or <see langword="null" /> to use the database default.</param>
|
||||
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
|
||||
public static OwnedNavigationBuilder HasColumnType(this OwnedNavigationBuilder builder, string? columnType)
|
||||
{
|
||||
|
|
|
@ -521,8 +521,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IColumnMappingBase>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.DefaultColumnMappings)
|
||||
?? Enumerable.Empty<IColumnMappingBase>();
|
||||
RelationalAnnotationNames.DefaultColumnMappings)
|
||||
?? Enumerable.Empty<IColumnMappingBase>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -534,8 +534,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IColumnMapping>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.TableColumnMappings)
|
||||
?? Enumerable.Empty<IColumnMapping>();
|
||||
RelationalAnnotationNames.TableColumnMappings)
|
||||
?? Enumerable.Empty<IColumnMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -547,8 +547,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IViewColumnMapping>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.ViewColumnMappings)
|
||||
?? Enumerable.Empty<IViewColumnMapping>();
|
||||
RelationalAnnotationNames.ViewColumnMappings)
|
||||
?? Enumerable.Empty<IViewColumnMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -560,8 +560,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<ISqlQueryColumnMapping>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.SqlQueryColumnMappings)
|
||||
?? Enumerable.Empty<ISqlQueryColumnMapping>();
|
||||
RelationalAnnotationNames.SqlQueryColumnMappings)
|
||||
?? Enumerable.Empty<ISqlQueryColumnMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -573,8 +573,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IFunctionColumnMapping>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.FunctionColumnMappings)
|
||||
?? Enumerable.Empty<IFunctionColumnMapping>();
|
||||
RelationalAnnotationNames.FunctionColumnMappings)
|
||||
?? Enumerable.Empty<IFunctionColumnMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -586,8 +586,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IStoredProcedureResultColumnMapping>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.InsertStoredProcedureResultColumnMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureResultColumnMapping>();
|
||||
RelationalAnnotationNames.InsertStoredProcedureResultColumnMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureResultColumnMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -599,8 +599,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IStoredProcedureParameterMapping>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.InsertStoredProcedureParameterMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureParameterMapping>();
|
||||
RelationalAnnotationNames.InsertStoredProcedureParameterMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureParameterMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -612,8 +612,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IStoredProcedureParameterMapping>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.DeleteStoredProcedureParameterMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureParameterMapping>();
|
||||
RelationalAnnotationNames.DeleteStoredProcedureParameterMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureParameterMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -625,8 +625,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IStoredProcedureResultColumnMapping>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.UpdateStoredProcedureResultColumnMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureResultColumnMapping>();
|
||||
RelationalAnnotationNames.UpdateStoredProcedureResultColumnMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureResultColumnMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -638,8 +638,8 @@ public static class RelationalPropertyExtensions
|
|||
{
|
||||
property.DeclaringType.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IStoredProcedureParameterMapping>?)property.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.UpdateStoredProcedureParameterMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureParameterMapping>();
|
||||
RelationalAnnotationNames.UpdateStoredProcedureParameterMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureParameterMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -43,8 +43,8 @@ public static class RelationalTypeBaseExtensions
|
|||
{
|
||||
typeBase.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<ITableMappingBase>?)typeBase.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.DefaultMappings)
|
||||
?? Enumerable.Empty<ITableMappingBase>();
|
||||
RelationalAnnotationNames.DefaultMappings)
|
||||
?? Enumerable.Empty<ITableMappingBase>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -56,8 +56,8 @@ public static class RelationalTypeBaseExtensions
|
|||
{
|
||||
typeBase.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<ITableMapping>?)typeBase.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.TableMappings)
|
||||
?? Enumerable.Empty<ITableMapping>();
|
||||
RelationalAnnotationNames.TableMappings)
|
||||
?? Enumerable.Empty<ITableMapping>();
|
||||
}
|
||||
|
||||
#endregion Table mapping
|
||||
|
@ -89,8 +89,8 @@ public static class RelationalTypeBaseExtensions
|
|||
{
|
||||
typeBase.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IViewMapping>?)typeBase.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.ViewMappings)
|
||||
?? Enumerable.Empty<IViewMapping>();
|
||||
RelationalAnnotationNames.ViewMappings)
|
||||
?? Enumerable.Empty<IViewMapping>();
|
||||
}
|
||||
|
||||
#endregion View mapping
|
||||
|
@ -114,8 +114,8 @@ public static class RelationalTypeBaseExtensions
|
|||
{
|
||||
typeBase.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<ISqlQueryMapping>?)typeBase.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.SqlQueryMappings)
|
||||
?? Enumerable.Empty<ISqlQueryMapping>();
|
||||
RelationalAnnotationNames.SqlQueryMappings)
|
||||
?? Enumerable.Empty<ISqlQueryMapping>();
|
||||
}
|
||||
|
||||
#endregion SQL query mapping
|
||||
|
@ -139,8 +139,8 @@ public static class RelationalTypeBaseExtensions
|
|||
{
|
||||
typeBase.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IFunctionMapping>?)typeBase.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.FunctionMappings)
|
||||
?? Enumerable.Empty<IFunctionMapping>();
|
||||
RelationalAnnotationNames.FunctionMappings)
|
||||
?? Enumerable.Empty<IFunctionMapping>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -209,7 +209,9 @@ public static class RelationalTypeBaseExtensions
|
|||
public static IEnumerable<IStoredProcedureMapping> GetInsertStoredProcedureMappings(this ITypeBase typeBase)
|
||||
{
|
||||
typeBase.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IStoredProcedureMapping>?)typeBase.FindRuntimeAnnotationValue(RelationalAnnotationNames.InsertStoredProcedureMappings) ?? Enumerable.Empty<IStoredProcedureMapping>();
|
||||
return (IEnumerable<IStoredProcedureMapping>?)typeBase.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.InsertStoredProcedureMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -220,7 +222,9 @@ public static class RelationalTypeBaseExtensions
|
|||
public static IEnumerable<IStoredProcedureMapping> GetDeleteStoredProcedureMappings(this ITypeBase typeBase)
|
||||
{
|
||||
typeBase.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IStoredProcedureMapping>?)typeBase.FindRuntimeAnnotationValue(RelationalAnnotationNames.DeleteStoredProcedureMappings) ?? Enumerable.Empty<IStoredProcedureMapping>();
|
||||
return (IEnumerable<IStoredProcedureMapping>?)typeBase.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.DeleteStoredProcedureMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureMapping>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -231,7 +235,9 @@ public static class RelationalTypeBaseExtensions
|
|||
public static IEnumerable<IStoredProcedureMapping> GetUpdateStoredProcedureMappings(this ITypeBase typeBase)
|
||||
{
|
||||
typeBase.Model.EnsureRelationalModel();
|
||||
return (IEnumerable<IStoredProcedureMapping>?)typeBase.FindRuntimeAnnotationValue(RelationalAnnotationNames.UpdateStoredProcedureMappings) ?? Enumerable.Empty<IStoredProcedureMapping>();
|
||||
return (IEnumerable<IStoredProcedureMapping>?)typeBase.FindRuntimeAnnotationValue(
|
||||
RelationalAnnotationNames.UpdateStoredProcedureMappings)
|
||||
?? Enumerable.Empty<IStoredProcedureMapping>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -368,7 +374,6 @@ public static class RelationalTypeBaseExtensions
|
|||
? entityType.GetContainerColumnName()
|
||||
: ((IReadOnlyComplexType)typeBase).GetContainerColumnName();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the column type to use for the container column to which the type is mapped.
|
||||
/// </summary>
|
||||
|
|
|
@ -103,7 +103,7 @@ public abstract class RelationalDbContextOptionsBuilder<TBuilder, TExtension> :
|
|||
/// <remarks>
|
||||
/// See <see href="https://aka.ms/efcore-docs-migrations">Database migrations</see> for more information and examples.
|
||||
/// </remarks>
|
||||
/// <param name="assembly">The <see cref="Assembly"/> where the migrations are located.</param>
|
||||
/// <param name="assembly">The <see cref="Assembly" /> where the migrations are located.</param>
|
||||
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
|
||||
public virtual TBuilder MigrationsAssembly(Assembly assembly)
|
||||
=> WithOption(e => (TExtension)e.WithMigrationsAssembly(assembly));
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче