This commit is contained in:
Arthur Vickers 2024-08-15 15:44:34 +01:00
Родитель e88fa4a92c
Коммит 3c20186392
403 изменённых файлов: 4551 добавлений и 3867 удалений

Просмотреть файл

@ -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));

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше