From e7358c93cf4f77669f793d4e132c67dd474213e8 Mon Sep 17 00:00:00 2001 From: Smit Patel Date: Tue, 6 Apr 2021 14:30:55 -0700 Subject: [PATCH] Update exception messages for optional dependents Address PR feedback --- .../Properties/RelationalStrings.Designer.cs | 8 +-- .../Properties/RelationalStrings.resx | 6 +- .../TableSplittingTestBase.cs | 2 +- .../RelationalModelValidatorTest.cs | 24 ++++++- .../DataAnnotationTestBase.cs | 2 + .../LazyLoadProxyTestBase.cs | 57 +++++++++++----- .../ChangedChangingMonsterContext.cs | 7 ++ .../TestModels/ChangedOnlyMonsterContext.cs | 7 ++ .../TestModels/MonsterModel.cs | 1 + .../TestModels/SnapshotMonsterContext.cs | 1 + .../TransportationModel/FuelTank.cs | 2 +- .../TransportationModel/OperatorDetails.cs | 6 +- .../TransportationContext.cs | 4 +- .../DataAnnotationSqlServerTest.cs | 28 +++++--- .../Query/QueryBugsTest.cs | 67 ++++++++++++------- .../SqlServerEndToEndTest.cs | 1 + .../TPTTableSplittingSqlServerTest.cs | 18 ++--- .../TableSplittingSqlServerTest.cs | 24 +++---- .../DataAnnotationSqliteTest.cs | 12 ++-- 19 files changed, 182 insertions(+), 95 deletions(-) diff --git a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs index 9732f2c63cc..515779e518a 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs +++ b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs @@ -894,7 +894,7 @@ public static string NullTypeMappingInSqlTree(object? sqlExpression) sqlExpression); /// - /// Entity type '{entityType}' is an optional dependent containing other dependents in table sharing without any required non shared property to identify if the entity type exist. If all nullable properties contain null value in database then an object instance won't be materialized in the query causing nested dependent's values to be lost. + /// Entity type '{entityType}' is an optional dependent using table sharing and containing other dependents without any required non shared property to identify whether the entity exists. If all nullable properties contain a null value in database then an object instance won't be created in the query causing nested dependent's values to be lost. Add a required property to create instances with null values for other properties or mark the incoming navigation as required to always create an instance. /// public static string OptionalDependentWithDependentWithoutIdentifyingProperty(object? entityType) => string.Format( @@ -2222,7 +2222,7 @@ public static EventDefinition LogOpeningConnection(IDiagnosticsL } /// - /// Entity type '{entityType}' is an optional dependent in table sharing without any required non shared property to identify if the entity type exist. If all nullable properties contain null value in database then an object instance won't be materialized in the query. + /// The entity type '{entityType}' is an optional dependent using table sharing without any required non shared property that could be used to identify whether the entity exists. If all nullable properties contain a null value in database then an object instance won't be created in the query. Add a required property to create instances with null values for other properties or mark the incoming navigation as required to always create an instance. /// public static EventDefinition LogOptionalDependentWithoutIdentifyingProperty(IDiagnosticsLogger logger) { @@ -2235,8 +2235,8 @@ public static EventDefinition LogOptionalDependentWithoutIdentifyingProp static logger => new EventDefinition( logger.Options, RelationalEventId.OptionalDependentWithoutIdentifyingPropertyWarning, - LogLevel.Error, - "RelationalEventId.ModelValidationOptionalDependentWithoutIdentifyingPropertyWarning", + LogLevel.Warning, + "RelationalEventId.OptionalDependentWithoutIdentifyingPropertyWarning", level => LoggerMessage.Define( level, RelationalEventId.OptionalDependentWithoutIdentifyingPropertyWarning, diff --git a/src/EFCore.Relational/Properties/RelationalStrings.resx b/src/EFCore.Relational/Properties/RelationalStrings.resx index 1b458cda98b..39dab27797d 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.resx +++ b/src/EFCore.Relational/Properties/RelationalStrings.resx @@ -551,8 +551,8 @@ Debug RelationalEventId.ConnectionOpening string string - Entity type '{entityType}' is an optional dependent in table sharing without any required non shared property to identify if the entity type exist. If all nullable properties contain null value in database then an object instance won't be materialized in the query. - Error RelationalEventId.ModelValidationOptionalDependentWithoutIdentifyingPropertyWarning string + The entity type '{entityType}' is an optional dependent using table sharing without any required non shared property that could be used to identify whether the entity exists. If all nullable properties contain a null value in database then an object instance won't be created in the query. Add a required property to create instances with null values for other properties or mark the incoming navigation as required to always create an instance. + Warning RelationalEventId.OptionalDependentWithoutIdentifyingPropertyWarning string Possible unintended use of method 'Equals' for arguments '{left}' and '{right}' of different types in a query. This comparison will always return false. @@ -680,7 +680,7 @@ Expression '{sqlExpression}' in the SQL tree does not have a type mapping assigned. - Entity type '{entityType}' is an optional dependent containing other dependents in table sharing without any required non shared property to identify if the entity type exist. If all nullable properties contain null value in database then an object instance won't be materialized in the query causing nested dependent's values to be lost. + Entity type '{entityType}' is an optional dependent using table sharing and containing other dependents without any required non shared property to identify whether the entity exists. If all nullable properties contain a null value in database then an object instance won't be created in the query causing nested dependent's values to be lost. Add a required property to create instances with null values for other properties or mark the incoming navigation as required to always create an instance. Cannot use the value provided for parameter '{parameter}' because it isn't assignable to type object[]. diff --git a/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs b/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs index cd2a979a711..8d00a4643c7 100644 --- a/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/TableSplittingTestBase.cs @@ -378,7 +378,7 @@ public virtual async Task Can_insert_dependent_with_just_one_parent() context.Add( new FuelTank { - Capacity = "10000 l", + Capacity = 10000_1, FuelType = "Gas", VehicleName = "Fuel transport" }); diff --git a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs index 88dd040c242..040c92a8bf6 100644 --- a/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs +++ b/test/EFCore.Relational.Tests/Infrastructure/RelationalModelValidatorTest.cs @@ -335,7 +335,7 @@ public virtual void Passes_on_not_configured_shared_columns_with_shared_table() } [ConditionalFact] - public virtual void Throws_on_not_configured_shared_columns_with_shared_table() + public virtual void Throws_on_not_configured_shared_columns_with_shared_table_with_dependents() { var modelBuilder = CreateConventionalModelBuilder(); @@ -348,6 +348,17 @@ public virtual void Throws_on_not_configured_shared_columns_with_shared_table() VerifyError(RelationalStrings.OptionalDependentWithDependentWithoutIdentifyingProperty(nameof(A)), modelBuilder.Model); } + [ConditionalFact] + public virtual void Warns_on_not_configured_shared_columns_with_shared_table() + { + var modelBuilder = CreateConventionalModelBuilder(); + + modelBuilder.Entity().OwnsOne(e => e.Owned); + + var definition = RelationalResources.LogOptionalDependentWithoutIdentifyingProperty(new TestLogger()); + VerifyWarning(definition.GenerateMessage(nameof(OwnedEntity)), modelBuilder.Model); + } + [ConditionalFact] public virtual void Detects_incompatible_shared_columns_with_shared_table() { @@ -2000,6 +2011,17 @@ protected class Employee : Person { } + protected class Owner + { + public int Id { get; set; } + public OwnedEntity Owned { get; set; } + } + + protected class OwnedEntity + { + public string Value { get; set; } + } + public class TestDecimalToLongConverter : ValueConverter { private static readonly Expression> convertToProviderExpression = d => (long)(d * 100); diff --git a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs index 0cd4b3594e4..3c8f21917b2 100644 --- a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs +++ b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs @@ -2486,6 +2486,7 @@ public class StreetAddress { public string Street { get; set; } public string City { get; set; } + public int ZipCode { get; set; } } public class Order @@ -2630,6 +2631,7 @@ protected class Two [Owned] protected class Details { + public int Value { get; set; } public string Name { get; set; } } diff --git a/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs b/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs index 32c6d79be7d..6464a00b96b 100644 --- a/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs +++ b/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs @@ -2083,42 +2083,51 @@ public virtual void Can_serialize_proxies_to_JSON() { ""Writer"": { ""FirstName"": ""firstNameWriter0"", - ""LastName"": ""lastNameWriter0"" + ""LastName"": ""lastNameWriter0"", + ""Alive"": false }, ""Reader"": { ""FirstName"": ""firstNameReader0"", - ""LastName"": ""lastNameReader0"" + ""LastName"": ""lastNameReader0"", + ""Alive"": false }, ""Host"": { - ""HostName"": ""127.0.0.1"" + ""HostName"": ""127.0.0.1"", + ""Rating"": 0.0 }, ""Id"": 1 }, { ""Writer"": { ""FirstName"": ""firstNameWriter1"", - ""LastName"": ""lastNameWriter1"" + ""LastName"": ""lastNameWriter1"", + ""Alive"": false }, ""Reader"": { ""FirstName"": ""firstNameReader1"", - ""LastName"": ""lastNameReader1"" + ""LastName"": ""lastNameReader1"", + ""Alive"": false }, ""Host"": { - ""HostName"": ""127.0.0.2"" + ""HostName"": ""127.0.0.2"", + ""Rating"": 0.0 }, ""Id"": 2 }, { ""Writer"": { ""FirstName"": ""firstNameWriter2"", - ""LastName"": ""lastNameWriter2"" + ""LastName"": ""lastNameWriter2"", + ""Alive"": false }, ""Reader"": { ""FirstName"": ""firstNameReader2"", - ""LastName"": ""lastNameReader2"" + ""LastName"": ""lastNameReader2"", + ""Alive"": false }, ""Host"": { - ""HostName"": ""127.0.0.3"" + ""HostName"": ""127.0.0.3"", + ""Rating"": 0.0 }, ""Id"": 3 } @@ -2145,16 +2154,19 @@ public virtual void Can_serialize_proxies_to_JSON() ""Writer"": { ""$id"": ""3"", ""FirstName"": ""firstNameWriter0"", - ""LastName"": ""lastNameWriter0"" + ""LastName"": ""lastNameWriter0"", + ""Alive"": false }, ""Reader"": { ""$id"": ""4"", ""FirstName"": ""firstNameReader0"", - ""LastName"": ""lastNameReader0"" + ""LastName"": ""lastNameReader0"", + ""Alive"": false }, ""Host"": { ""$id"": ""5"", - ""HostName"": ""127.0.0.1"" + ""HostName"": ""127.0.0.1"", + ""Rating"": 0 } }, { @@ -2163,16 +2175,19 @@ public virtual void Can_serialize_proxies_to_JSON() ""Writer"": { ""$id"": ""7"", ""FirstName"": ""firstNameWriter1"", - ""LastName"": ""lastNameWriter1"" + ""LastName"": ""lastNameWriter1"", + ""Alive"": false }, ""Reader"": { ""$id"": ""8"", ""FirstName"": ""firstNameReader1"", - ""LastName"": ""lastNameReader1"" + ""LastName"": ""lastNameReader1"", + ""Alive"": false }, ""Host"": { ""$id"": ""9"", - ""HostName"": ""127.0.0.2"" + ""HostName"": ""127.0.0.2"", + ""Rating"": 0 } }, { @@ -2181,16 +2196,19 @@ public virtual void Can_serialize_proxies_to_JSON() ""Writer"": { ""$id"": ""11"", ""FirstName"": ""firstNameWriter2"", - ""LastName"": ""lastNameWriter2"" + ""LastName"": ""lastNameWriter2"", + ""Alive"": false }, ""Reader"": { ""$id"": ""12"", ""FirstName"": ""firstNameReader2"", - ""LastName"": ""lastNameReader2"" + ""LastName"": ""lastNameReader2"", + ""Alive"": false }, ""Host"": { ""$id"": ""13"", - ""HostName"": ""127.0.0.3"" + ""HostName"": ""127.0.0.3"", + ""Rating"": 0 } } ] @@ -2634,6 +2652,7 @@ public class Person { public string FirstName { get; set; } public string LastName { get; set; } + public bool Alive { get; set; } } public class Entity @@ -2658,6 +2677,7 @@ public class Parson : Entity public class Host { public string HostName { get; set; } + public double Rating { get; set; } } public abstract class Tribe @@ -2746,6 +2766,7 @@ public class OwnedAddress { public string Street { get; set; } public string PostalCode { get; set; } + public int CountryCode { get; set; } } protected DbContext CreateContext(bool lazyLoadingEnabled = false) diff --git a/test/EFCore.Specification.Tests/TestModels/ChangedChangingMonsterContext.cs b/test/EFCore.Specification.Tests/TestModels/ChangedChangingMonsterContext.cs index 7601d5e1d35..d1b89bc50eb 100644 --- a/test/EFCore.Specification.Tests/TestModels/ChangedChangingMonsterContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/ChangedChangingMonsterContext.cs @@ -304,9 +304,16 @@ public virtual IComputerDetail ComputerDetail public class ConcurrencyInfo : NotificationEntity, IConcurrencyInfo { + private bool _active; private string _token; private DateTime? _queriedDateTime; + public bool Active + { + get => _active; + set => SetWithNotify(value, ref _active); + } + public string Token { get => _token; diff --git a/test/EFCore.Specification.Tests/TestModels/ChangedOnlyMonsterContext.cs b/test/EFCore.Specification.Tests/TestModels/ChangedOnlyMonsterContext.cs index f1aefbd5fb0..635360aa144 100644 --- a/test/EFCore.Specification.Tests/TestModels/ChangedOnlyMonsterContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/ChangedOnlyMonsterContext.cs @@ -299,9 +299,16 @@ public virtual IComputerDetail ComputerDetail public class ConcurrencyInfo : NotificationEntity, IConcurrencyInfo { + private bool _active; private string _token; private DateTime? _queriedDateTime; + public bool Active + { + get => _active; + set => SetWithNotify(value, ref _active); + } + public string Token { get => _token; diff --git a/test/EFCore.Specification.Tests/TestModels/MonsterModel.cs b/test/EFCore.Specification.Tests/TestModels/MonsterModel.cs index 5e774775aa8..6808fc22618 100644 --- a/test/EFCore.Specification.Tests/TestModels/MonsterModel.cs +++ b/test/EFCore.Specification.Tests/TestModels/MonsterModel.cs @@ -62,6 +62,7 @@ public interface IComputer public interface IConcurrencyInfo { + bool Active { get; set; } string Token { get; set; } DateTime? QueriedDateTime { get; set; } } diff --git a/test/EFCore.Specification.Tests/TestModels/SnapshotMonsterContext.cs b/test/EFCore.Specification.Tests/TestModels/SnapshotMonsterContext.cs index cce034052e7..c4f7a4858ee 100644 --- a/test/EFCore.Specification.Tests/TestModels/SnapshotMonsterContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/SnapshotMonsterContext.cs @@ -107,6 +107,7 @@ public class Computer : IComputer public class ConcurrencyInfo : IConcurrencyInfo { + public bool Active { get; set; } public string Token { get; set; } public DateTime? QueriedDateTime { get; set; } } diff --git a/test/EFCore.Specification.Tests/TestModels/TransportationModel/FuelTank.cs b/test/EFCore.Specification.Tests/TestModels/TransportationModel/FuelTank.cs index bb631ff7399..1e93c4e9c07 100644 --- a/test/EFCore.Specification.Tests/TestModels/TransportationModel/FuelTank.cs +++ b/test/EFCore.Specification.Tests/TestModels/TransportationModel/FuelTank.cs @@ -9,7 +9,7 @@ public class FuelTank { public string VehicleName { get; set; } public string FuelType { get; set; } - public string Capacity { get; set; } + public int Capacity { get; set; } public PoweredVehicle Vehicle { get; set; } public CombustionEngine Engine { get; set; } diff --git a/test/EFCore.Specification.Tests/TestModels/TransportationModel/OperatorDetails.cs b/test/EFCore.Specification.Tests/TestModels/TransportationModel/OperatorDetails.cs index e8974e8e79b..ff88a53050c 100644 --- a/test/EFCore.Specification.Tests/TestModels/TransportationModel/OperatorDetails.cs +++ b/test/EFCore.Specification.Tests/TestModels/TransportationModel/OperatorDetails.cs @@ -9,13 +9,15 @@ public class OperatorDetails { public string VehicleName { get; set; } public string Type { get; set; } + public bool Active { get; set; } public override bool Equals(object obj) => obj is OperatorDetails other && VehicleName == other.VehicleName - && Type == other.Type; + && Type == other.Type + && Active == other.Active; public override int GetHashCode() - => HashCode.Combine(VehicleName, Type); + => HashCode.Combine(VehicleName, Type, Active); } } diff --git a/test/EFCore.Specification.Tests/TestModels/TransportationModel/TransportationContext.cs b/test/EFCore.Specification.Tests/TestModels/TransportationModel/TransportationContext.cs index 305f3e93e28..16b6ff18741 100644 --- a/test/EFCore.Specification.Tests/TestModels/TransportationModel/TransportationContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/TransportationModel/TransportationContext.cs @@ -147,7 +147,7 @@ protected IEnumerable CreateVehicles() FuelTank = new FuelTank { FuelType = "Liquid oxygen and anhydrous ammonia", - Capacity = "11250 kg", + Capacity = 11250, VehicleName = "North American X-15A-2" }, VehicleName = "North American X-15A-2" @@ -168,7 +168,7 @@ protected IEnumerable CreateVehicles() FuelTank = new SolidFuelTank { FuelType = "Reduced smoke Hydroxyl-Terminated Polybutadiene", - Capacity = "22 kg", + Capacity = 22, GrainGeometry = "Cylindrical", VehicleName = "AIM-9M Sidewinder" }, diff --git a/test/EFCore.SqlServer.FunctionalTests/DataAnnotationSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/DataAnnotationSqlServerTest.cs index 432c8f3b23d..906fd7acd43 100644 --- a/test/EFCore.SqlServer.FunctionalTests/DataAnnotationSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/DataAnnotationSqlServerTest.cs @@ -159,11 +159,11 @@ public override void ConcurrencyCheckAttribute_throws_if_value_in_database_chang base.ConcurrencyCheckAttribute_throws_if_value_in_database_changed(); AssertSql( - @"SELECT TOP(1) [s].[Unique_No], [s].[MaxLengthProperty], [s].[Name], [s].[RowVersion], [s].[AdditionalDetails_Name], [s].[Details_Name] + @"SELECT TOP(1) [s].[Unique_No], [s].[MaxLengthProperty], [s].[Name], [s].[RowVersion], [s].[AdditionalDetails_Name], [s].[AdditionalDetails_Value], [s].[Details_Name], [s].[Details_Value] FROM [Sample] AS [s] WHERE [s].[Unique_No] = 1", // - @"SELECT TOP(1) [s].[Unique_No], [s].[MaxLengthProperty], [s].[Name], [s].[RowVersion], [s].[AdditionalDetails_Name], [s].[Details_Name] + @"SELECT TOP(1) [s].[Unique_No], [s].[MaxLengthProperty], [s].[Name], [s].[RowVersion], [s].[AdditionalDetails_Name], [s].[AdditionalDetails_Value], [s].[Details_Name], [s].[Details_Value] FROM [Sample] AS [s] WHERE [s].[Unique_No] = 1", // @@ -197,11 +197,13 @@ public override void DatabaseGeneratedAttribute_autogenerates_values_when_set_to @p1='Third' (Nullable = false) (Size = 4000) @p2='00000000-0000-0000-0000-000000000003' @p3='Third Additional Name' (Size = 4000) -@p4='Third Name' (Size = 4000) +@p4='0' (Nullable = true) +@p5='Third Name' (Size = 4000) +@p6='0' (Nullable = true) SET NOCOUNT ON; -INSERT INTO [Sample] ([MaxLengthProperty], [Name], [RowVersion], [AdditionalDetails_Name], [Details_Name]) -VALUES (@p0, @p1, @p2, @p3, @p4); +INSERT INTO [Sample] ([MaxLengthProperty], [Name], [RowVersion], [AdditionalDetails_Name], [AdditionalDetails_Value], [Details_Name], [Details_Value]) +VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6); SELECT [Unique_No] FROM [Sample] WHERE @@ROWCOUNT = 1 AND [Unique_No] = scope_identity();"); @@ -216,11 +218,13 @@ public override void MaxLengthAttribute_throws_while_inserting_value_longer_than @p1='ValidString' (Nullable = false) (Size = 4000) @p2='00000000-0000-0000-0000-000000000001' @p3='Third Additional Name' (Size = 4000) -@p4='Third Name' (Size = 4000) +@p4='0' (Nullable = true) +@p5='Third Name' (Size = 4000) +@p6='0' (Nullable = true) SET NOCOUNT ON; -INSERT INTO [Sample] ([MaxLengthProperty], [Name], [RowVersion], [AdditionalDetails_Name], [Details_Name]) -VALUES (@p0, @p1, @p2, @p3, @p4); +INSERT INTO [Sample] ([MaxLengthProperty], [Name], [RowVersion], [AdditionalDetails_Name], [AdditionalDetails_Value], [Details_Name], [Details_Value]) +VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6); SELECT [Unique_No] FROM [Sample] WHERE @@ROWCOUNT = 1 AND [Unique_No] = scope_identity();", @@ -229,11 +233,13 @@ FROM [Sample] @p1='ValidString' (Nullable = false) (Size = 4000) @p2='00000000-0000-0000-0000-000000000002' @p3='Third Additional Name' (Size = 4000) -@p4='Third Name' (Size = 4000) +@p4='0' (Nullable = true) +@p5='Third Name' (Size = 4000) +@p6='0' (Nullable = true) SET NOCOUNT ON; -INSERT INTO [Sample] ([MaxLengthProperty], [Name], [RowVersion], [AdditionalDetails_Name], [Details_Name]) -VALUES (@p0, @p1, @p2, @p3, @p4); +INSERT INTO [Sample] ([MaxLengthProperty], [Name], [RowVersion], [AdditionalDetails_Name], [AdditionalDetails_Value], [Details_Name], [Details_Value]) +VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6); SELECT [Unique_No] FROM [Sample] WHERE @@ROWCOUNT = 1 AND [Unique_No] = scope_identity();"); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs index 6ce50e9ac6f..9e03f2fa80f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs @@ -2105,11 +2105,10 @@ public async Task Include_collection_for_entity_with_owned_type_works() Assert.True(result[0].Cast.All(a => a.Details != null)); AssertSql( - @"SELECT [m].[Id], [m].[Title], [m].[Details_Info], [a].[Id], [a].[Movie9202Id], [a].[Name], [a].[Details_Info] + @"SELECT [m].[Id], [m].[Title], [m].[Details_Info], [m].[Details_Rating], [a].[Id], [a].[Movie9202Id], [a].[Name], [a].[Details_Info], [a].[Details_Rating] FROM [Movies] AS [m] LEFT JOIN [Actors] AS [a] ON [m].[Id] = [a].[Movie9202Id] ORDER BY [m].[Id], [a].[Id]"); - ClearLog(); } using (var context = contextFactory.CreateContext()) @@ -2123,7 +2122,12 @@ FROM [Movies] AS [m] Assert.True(result[0].Cast.All(a => a.Details != null)); AssertSql( - @"SELECT [m].[Id], [m].[Title], [m].[Details_Info], [a].[Id], [a].[Movie9202Id], [a].[Name], [a].[Details_Info] + @"SELECT [m].[Id], [m].[Title], [m].[Details_Info], [m].[Details_Rating], [a].[Id], [a].[Movie9202Id], [a].[Name], [a].[Details_Info], [a].[Details_Rating] +FROM [Movies] AS [m] +LEFT JOIN [Actors] AS [a] ON [m].[Id] = [a].[Movie9202Id] +ORDER BY [m].[Id], [a].[Id]", + // + @"SELECT [m].[Id], [m].[Title], [m].[Details_Info], [m].[Details_Rating], [a].[Id], [a].[Movie9202Id], [a].[Name], [a].[Details_Info], [a].[Details_Rating] FROM [Movies] AS [m] LEFT JOIN [Actors] AS [a] ON [m].[Id] = [a].[Movie9202Id] ORDER BY [m].[Id], [a].[Id]"); @@ -2190,6 +2194,7 @@ public class Actor9202 public class Details9202 { public string Info { get; set; } + public int Rating { get; set; } } } @@ -2829,7 +2834,7 @@ LEFT JOIN ( SELECT [t0].[Id], [t0].[AnotherEntity11818_Name] FROM [Table] AS [t0] INNER JOIN [Table] AS [t2] ON [t0].[Id] = [t2].[Id] - WHERE [t0].[AnotherEntity11818_Name] IS NOT NULL + WHERE [t0].[Exists] IS NOT NULL ) AS [t1] ON [t].[Id] = [t1].[Id] GROUP BY [t1].[AnotherEntity11818_Name]"); } @@ -2860,13 +2865,13 @@ LEFT JOIN ( SELECT [t0].[Id], [t0].[AnotherEntity11818_Name] FROM [Table] AS [t0] INNER JOIN [Table] AS [t2] ON [t0].[Id] = [t2].[Id] - WHERE [t0].[AnotherEntity11818_Name] IS NOT NULL + WHERE [t0].[Exists] IS NOT NULL ) AS [t1] ON [t].[Id] = [t1].[Id] LEFT JOIN ( SELECT [t4].[Id], [t4].[MaumarEntity11818_Name] FROM [Table] AS [t4] INNER JOIN [Table] AS [t5] ON [t4].[Id] = [t5].[Id] - WHERE [t4].[MaumarEntity11818_Name] IS NOT NULL + WHERE [t4].[MaumarEntity11818_Exists] IS NOT NULL ) AS [t3] ON [t].[Id] = [t3].[Id] GROUP BY [t1].[AnotherEntity11818_Name], [t3].[MaumarEntity11818_Name]"); } @@ -2895,13 +2900,13 @@ LEFT JOIN ( SELECT [t0].[Id], [t0].[AnotherEntity11818_Name] FROM [Table] AS [t0] INNER JOIN [Table] AS [t2] ON [t0].[Id] = [t2].[Id] - WHERE [t0].[AnotherEntity11818_Name] IS NOT NULL + WHERE [t0].[Exists] IS NOT NULL ) AS [t1] ON [t].[Id] = [t1].[Id] LEFT JOIN ( SELECT [t4].[Id], [t4].[MaumarEntity11818_Name] FROM [Table] AS [t4] INNER JOIN [Table] AS [t5] ON [t4].[Id] = [t5].[Id] - WHERE [t4].[MaumarEntity11818_Name] IS NOT NULL + WHERE [t4].[MaumarEntity11818_Exists] IS NOT NULL ) AS [t3] ON [t].[Id] = [t3].[Id] GROUP BY [t1].[AnotherEntity11818_Name], [t3].[MaumarEntity11818_Name]"); } @@ -2941,12 +2946,14 @@ public class AnotherEntity11818 { public int Id { get; set; } public string Name { get; set; } + public bool Exists { get; set; } } public class MaumarEntity11818 { public int Id { get; set; } public string Name { get; set; } + public bool Exists { get; set; } } } @@ -3598,6 +3605,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) [Owned] public class OptionalChangePoint12170 { + public int Value { get; set; } public DateTime? Timestamp { get; set; } } @@ -4889,14 +4897,14 @@ public virtual async Task Expression_tree_constructed_via_interface_works_17276( var query = MyContext17276.List17276(context.RemovableEntities); AssertSql( - @"SELECT [r].[Id], [r].[IsRemoved], [r].[Removed], [r].[RemovedByUser], [r].[OwnedEntity_OwnedValue] + @"SELECT [r].[Id], [r].[IsRemoved], [r].[Removed], [r].[RemovedByUser], [r].[OwnedEntity_Exists], [r].[OwnedEntity_OwnedValue] FROM [RemovableEntities] AS [r] WHERE [r].[IsRemoved] = CAST(0 AS bit)"); - ClearLog(); } using (var context = contextFactory.CreateContext()) { + ClearLog(); var query = context.Parents .Where(p => EF.Property(EF.Property(p, "RemovableEntity"), "IsRemoved")) .ToList(); @@ -4906,25 +4914,26 @@ FROM [RemovableEntities] AS [r] FROM [Parents] AS [p] LEFT JOIN [RemovableEntities] AS [r] ON [p].[RemovableEntityId] = [r].[Id] WHERE [r].[IsRemoved] = CAST(1 AS bit)"); - ClearLog(); } using (var context = contextFactory.CreateContext()) { + ClearLog(); var query = context.RemovableEntities .Where(p => EF.Property(EF.Property(p, "OwnedEntity"), "OwnedValue") == "Abc") .ToList(); AssertSql( - @"SELECT [r].[Id], [r].[IsRemoved], [r].[Removed], [r].[RemovedByUser], [r].[OwnedEntity_OwnedValue] + @"SELECT [r].[Id], [r].[IsRemoved], [r].[Removed], [r].[RemovedByUser], [r].[OwnedEntity_Exists], [r].[OwnedEntity_OwnedValue] FROM [RemovableEntities] AS [r] WHERE [r].[OwnedEntity_OwnedValue] = N'Abc'"); - ClearLog(); } // #16759 using (var context = contextFactory.CreateContext()) { + + ClearLog(); var specification = new MyContext17276.Specification17276(1); var entities = context.Set().Where(specification.Criteria).ToList(); @@ -4981,6 +4990,7 @@ public class Parent17276 : IHasId17276 public class OwnedEntity : IOwned { public string OwnedValue { get; set; } + public int Exists { get; set; } } public interface IHasId17276 @@ -4991,6 +5001,7 @@ public interface IHasId17276 public interface IOwned { string OwnedValue { get; } + int Exists { get; } } public class Specification17276 @@ -6257,6 +6268,7 @@ public class SubEntity19138 : BaseEntity19138 public class Owned19138 { public string OwnedData { get; set; } + public int Value { get; set; } } public class OtherEntity19138 @@ -7520,7 +7532,7 @@ public virtual async Task Nested_owned_required_dependents_are_materialized() var result = Assert.Single(query); Assert.NotNull(result.Contact); Assert.NotNull(result.Contact.Address); - Assert.Equal("12345", result.Contact.Address.Zip); + Assert.Equal(12345, result.Contact.Address.Zip); AssertSql( @"SELECT [e].[Id], [e].[Contact_Name], [e].[Contact_Address_City], [e].[Contact_Address_State], [e].[Contact_Address_Street], [e].[Contact_Address_Zip] @@ -7554,7 +7566,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) public void Seed() { - Add(new Entity21807 { Id = "1", Contact = new Contact21807 { Address = new Address21807 { Zip = "12345" } } }); + Add(new Entity21807 { Id = "1", Contact = new Contact21807 { Address = new Address21807 { Zip = 12345 } } }); SaveChanges(); } @@ -7576,7 +7588,7 @@ public class Address21807 public string Street { get; set; } public string City { get; set; } public string State { get; set; } - public string Zip { get; set; } + public int Zip { get; set; } } } @@ -7605,7 +7617,7 @@ public virtual async Task Optional_dependent_is_null_when_sharing_required_colum Assert.NotNull(query[2].Contact.Address); AssertSql( - @"SELECT [u].[Id], [u].[RowVersion], [u].[Contact_MobileNumber], [u].[SharedProperty], [u].[RowVersion], [u].[Contact_Address_City], [u].[Contact_Address_Zip], [u].[Data_Data] + @"SELECT [u].[Id], [u].[RowVersion], [u].[Contact_MobileNumber], [u].[SharedProperty], [u].[RowVersion], [u].[Contact_Address_City], [u].[Contact_Address_Zip], [u].[Data_Data], [u].[Data_Exists] FROM [User22054] AS [u] ORDER BY [u].[Id] DESC"); } @@ -7665,7 +7677,7 @@ public void Seed() Address = new Address22054 { City = "Seattle", - Zip = "12345", + Zip = 12345, SharedProperty = "Value1" } } @@ -7696,6 +7708,7 @@ public class User22054 public class Data22054 { public string Data { get; set; } + public bool Exists { get; set; } } public class Contact22054 @@ -7709,7 +7722,7 @@ public class Address22054 { public string City { get; set; } public string SharedProperty { get; set; } - public string Zip { get; set; } + public int Zip { get; set; } } } @@ -7730,18 +7743,18 @@ public virtual async Task Owned_entity_multiple_level_in_aggregate() Assert.Equal(20, aggregate.FirstValueObject.SecondValueObjects[0].ThirdValueObjects[0].FourthValueObject.FifthValueObjects[0].AnyValue); AssertSql( - @"SELECT [t].[Id], [t2].[Id], [t2].[AggregateId], [t2].[Id0], [t2].[AnyValue], [t2].[SecondValueObjectId], [t2].[Id1], [t2].[SecondValueObjectId0], [t2].[Id00], [t2].[AnyValue0], [t2].[ThirdValueObjectId] + @"SELECT [t].[Id], [t].[FirstValueObject_Value], [t2].[Id], [t2].[AggregateId], [t2].[FourthValueObject_Value], [t2].[Id0], [t2].[AnyValue], [t2].[SecondValueObjectId], [t2].[Id1], [t2].[SecondValueObjectId0], [t2].[FourthValueObject_Value0], [t2].[Id00], [t2].[AnyValue0], [t2].[ThirdValueObjectId] FROM ( - SELECT TOP(1) [a].[Id] + SELECT TOP(1) [a].[Id], [a].[FirstValueObject_Value] FROM [Aggregates] AS [a] ORDER BY [a].[Id] DESC ) AS [t] LEFT JOIN ( - SELECT [s].[Id], [s].[AggregateId], [f].[Id] AS [Id0], [f].[AnyValue], [f].[SecondValueObjectId], [t1].[Id] AS [Id1], [t1].[SecondValueObjectId] AS [SecondValueObjectId0], [t1].[Id0] AS [Id00], [t1].[AnyValue] AS [AnyValue0], [t1].[ThirdValueObjectId] + SELECT [s].[Id], [s].[AggregateId], [s].[FourthValueObject_Value], [f].[Id] AS [Id0], [f].[AnyValue], [f].[SecondValueObjectId], [t1].[Id] AS [Id1], [t1].[SecondValueObjectId] AS [SecondValueObjectId0], [t1].[FourthValueObject_Value] AS [FourthValueObject_Value0], [t1].[Id0] AS [Id00], [t1].[AnyValue] AS [AnyValue0], [t1].[ThirdValueObjectId] FROM [SecondValueObjects] AS [s] LEFT JOIN [FourthFifthValueObjects] AS [f] ON [s].[Id] = [f].[SecondValueObjectId] LEFT JOIN ( - SELECT [t0].[Id], [t0].[SecondValueObjectId], [t3].[Id] AS [Id0], [t3].[AnyValue], [t3].[ThirdValueObjectId] + SELECT [t0].[Id], [t0].[SecondValueObjectId], [t0].[FourthValueObject_Value], [t3].[Id] AS [Id0], [t3].[AnyValue], [t3].[ThirdValueObjectId] FROM [ThirdValueObjects] AS [t0] LEFT JOIN [ThirdFifthValueObjects] AS [t3] ON [t0].[Id] = [t3].[ThirdValueObjectId] ) AS [t1] ON [s].[Id] = [t1].[SecondValueObjectId] @@ -7855,6 +7868,7 @@ public class Aggregate14911 public class FirstValueObject14911 { + public int Value { get; set; } public List SecondValueObjects { get; set; } } @@ -7871,6 +7885,7 @@ public class ThirdValueObject14911 public class FourthValueObject14911 { + public int Value { get; set; } public List FifthValueObjects { get; set; } } @@ -8669,10 +8684,9 @@ public virtual async Task Can_query_point_with_buffered_data_reader() Assert.NotNull(testUser); AssertSql( - new[] { - @"SELECT TOP(1) [l].[Id], [l].[Name], [l].[Address_County], [l].[Address_Line1], [l].[Address_Line2], [l].[Address_Point], [l].[Address_Postcode], [l].[Address_Town] + @"SELECT TOP(1) [l].[Id], [l].[Name], [l].[Address_County], [l].[Address_Line1], [l].[Address_Line2], [l].[Address_Point], [l].[Address_Postcode], [l].[Address_Town], [l].[Address_Value] FROM [Locations] AS [l] -WHERE [l].[Name] = N'My Location'" }); +WHERE [l].[Name] = N'My Location'"); } } @@ -8710,6 +8724,7 @@ public class Address23282 public string Town { get; set; } public string County { get; set; } public string Postcode { get; set; } + public int Value { get; set; } public Point Point { get; set; } } diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs index e86bb7f2890..d19516f599b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs @@ -455,6 +455,7 @@ private sealed class Category private sealed class FileSource { public Guid? FileId { get; set; } + public bool Deleted { get; set; } } [ConditionalFact] diff --git a/test/EFCore.SqlServer.FunctionalTests/TPTTableSplittingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/TPTTableSplittingSqlServerTest.cs index 792dde7ef72..658a2981266 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TPTTableSplittingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TPTTableSplittingSqlServerTest.cs @@ -25,7 +25,7 @@ public override async Task Can_use_with_redundant_relationships() @"SELECT [v].[Name], [v].[SeatingCapacity], [c].[AttachedVehicleName], CASE WHEN [c].[Name] IS NOT NULL THEN N'CompositeVehicle' WHEN [p].[Name] IS NOT NULL THEN N'PoweredVehicle' -END AS [Discriminator], [t0].[Name], [t0].[Operator_Name], [t0].[LicenseType], [t0].[Discriminator], [t1].[Name], [t1].[Type], [t4].[Name], [t4].[Computed], [t4].[Description], [t4].[Discriminator], [t6].[VehicleName], [t6].[Capacity], [t6].[FuelType], [t6].[GrainGeometry], [t6].[Discriminator] +END AS [Discriminator], [t0].[Name], [t0].[Operator_Name], [t0].[LicenseType], [t0].[Discriminator], [t1].[Name], [t1].[Active], [t1].[Type], [t4].[Name], [t4].[Computed], [t4].[Description], [t4].[Discriminator], [t6].[VehicleName], [t6].[Capacity], [t6].[FuelType], [t6].[GrainGeometry], [t6].[Discriminator] FROM [Vehicles] AS [v] LEFT JOIN [PoweredVehicles] AS [p] ON [v].[Name] = [p].[Name] LEFT JOIN [CompositeVehicles] AS [c] ON [v].[Name] = [c].[Name] @@ -41,7 +41,7 @@ FROM [Vehicles] AS [v1] ) AS [t] ON [v0].[Name] = [t].[Name] ) AS [t0] ON [v].[Name] = [t0].[Name] LEFT JOIN ( - SELECT [v2].[Name], [v2].[Type] + SELECT [v2].[Name], [v2].[Active], [v2].[Type] FROM [Vehicles] AS [v2] INNER JOIN ( SELECT [v3].[Name] @@ -51,7 +51,7 @@ SELECT [v4].[Name] FROM [Vehicles] AS [v4] ) AS [t3] ON [v3].[Name] = [t3].[Name] ) AS [t2] ON [v2].[Name] = [t2].[Name] - WHERE [v2].[Type] IS NOT NULL + WHERE [v2].[Active] IS NOT NULL ) AS [t1] ON [t0].[Name] = [t1].[Name] LEFT JOIN ( SELECT [p2].[Name], [p2].[Computed], [p2].[Description], CASE @@ -81,7 +81,7 @@ SELECT [p4].[Name] FROM [PoweredVehicles] AS [p4] INNER JOIN [CombustionEngines] AS [c6] ON [p4].[Name] = [c6].[VehicleName] ) AS [t7] ON [c5].[VehicleName] = [t7].[Name] - WHERE [c5].[Capacity] IS NOT NULL OR [c5].[FuelType] IS NOT NULL + WHERE [c5].[Capacity] IS NOT NULL ) AS [t6] ON [t4].[Name] = [t6].[VehicleName] ORDER BY [v].[Name]"); } @@ -143,7 +143,7 @@ SELECT [p].[Name] FROM [PoweredVehicles] AS [p] INNER JOIN [CombustionEngines] AS [c0] ON [p].[Name] = [c0].[VehicleName] ) AS [t] ON [c].[VehicleName] = [t].[Name] -WHERE [c].[Capacity] IS NOT NULL OR [c].[FuelType] IS NOT NULL"); +WHERE [c].[Capacity] IS NOT NULL"); } public override async Task Can_query_shared_derived_nonhierarchy() @@ -158,7 +158,7 @@ SELECT [p].[Name] FROM [PoweredVehicles] AS [p] INNER JOIN [CombustionEngines] AS [c0] ON [p].[Name] = [c0].[VehicleName] ) AS [t] ON [c].[VehicleName] = [t].[Name] -WHERE [c].[Capacity] IS NOT NULL OR [c].[FuelType] IS NOT NULL"); +WHERE [c].[Capacity] IS NOT NULL"); } public override async Task Can_query_shared_derived_nonhierarchy_all_required() @@ -258,7 +258,7 @@ public override async Task Optional_dependent_materialized_when_no_properties() @"SELECT TOP(1) [v].[Name], [v].[SeatingCapacity], [c].[AttachedVehicleName], CASE WHEN [c].[Name] IS NOT NULL THEN N'CompositeVehicle' WHEN [p].[Name] IS NOT NULL THEN N'PoweredVehicle' -END AS [Discriminator], [t0].[Name], [t0].[Operator_Name], [t0].[LicenseType], [t0].[Discriminator], [t1].[Name], [t1].[Type] +END AS [Discriminator], [t0].[Name], [t0].[Operator_Name], [t0].[LicenseType], [t0].[Discriminator], [t1].[Name], [t1].[Active], [t1].[Type] FROM [Vehicles] AS [v] LEFT JOIN [PoweredVehicles] AS [p] ON [v].[Name] = [p].[Name] LEFT JOIN [CompositeVehicles] AS [c] ON [v].[Name] = [c].[Name] @@ -274,7 +274,7 @@ FROM [Vehicles] AS [v1] ) AS [t] ON [v0].[Name] = [t].[Name] ) AS [t0] ON [v].[Name] = [t0].[Name] LEFT JOIN ( - SELECT [v2].[Name], [v2].[Type] + SELECT [v2].[Name], [v2].[Active], [v2].[Type] FROM [Vehicles] AS [v2] INNER JOIN ( SELECT [v3].[Name] @@ -284,7 +284,7 @@ SELECT [v4].[Name] FROM [Vehicles] AS [v4] ) AS [t3] ON [v3].[Name] = [t3].[Name] ) AS [t2] ON [v2].[Name] = [t2].[Name] - WHERE [v2].[Type] IS NOT NULL + WHERE [v2].[Active] IS NOT NULL ) AS [t1] ON [t0].[Name] = [t1].[Name] WHERE [v].[Name] = N'AIM-9M Sidewinder' ORDER BY [v].[Name]"); diff --git a/test/EFCore.SqlServer.FunctionalTests/TableSplittingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/TableSplittingSqlServerTest.cs index 9a7308694a6..8a57673b121 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TableSplittingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TableSplittingSqlServerTest.cs @@ -24,7 +24,7 @@ public override async Task Can_use_with_redundant_relationships() // TODO: [Name] shouldn't be selected multiple times and no joins are needed AssertSql( - @"SELECT [v].[Name], [v].[Discriminator], [v].[SeatingCapacity], [v].[AttachedVehicleName], [t].[Name], [t].[Operator_Discriminator], [t].[Operator_Name], [t].[LicenseType], [t0].[Name], [t0].[Type], [t2].[Name], [t2].[Computed], [t2].[Description], [t2].[Engine_Discriminator], [t4].[Name], [t4].[Capacity], [t4].[FuelTank_Discriminator], [t4].[FuelType], [t4].[GrainGeometry] + @"SELECT [v].[Name], [v].[Discriminator], [v].[SeatingCapacity], [v].[AttachedVehicleName], [t].[Name], [t].[Operator_Discriminator], [t].[Operator_Name], [t].[LicenseType], [t0].[Name], [t0].[Active], [t0].[Type], [t2].[Name], [t2].[Computed], [t2].[Description], [t2].[Engine_Discriminator], [t4].[Name], [t4].[Capacity], [t4].[FuelTank_Discriminator], [t4].[FuelType], [t4].[GrainGeometry] FROM [Vehicles] AS [v] LEFT JOIN ( SELECT [v0].[Name], [v0].[Operator_Discriminator], [v0].[Operator_Name], [v0].[LicenseType] @@ -32,14 +32,14 @@ FROM [Vehicles] AS [v0] INNER JOIN [Vehicles] AS [v1] ON [v0].[Name] = [v1].[Name] ) AS [t] ON [v].[Name] = [t].[Name] LEFT JOIN ( - SELECT [v2].[Name], [v2].[Type] + SELECT [v2].[Name], [v2].[Active], [v2].[Type] FROM [Vehicles] AS [v2] INNER JOIN ( SELECT [v3].[Name] FROM [Vehicles] AS [v3] INNER JOIN [Vehicles] AS [v4] ON [v3].[Name] = [v4].[Name] ) AS [t1] ON [v2].[Name] = [t1].[Name] - WHERE [v2].[Type] IS NOT NULL + WHERE [v2].[Active] IS NOT NULL ) AS [t0] ON [t].[Name] = [t0].[Name] LEFT JOIN ( SELECT [v5].[Name], [v5].[Computed], [v5].[Description], [v5].[Engine_Discriminator] @@ -59,7 +59,7 @@ INNER JOIN ( FROM [Vehicles] AS [v8] WHERE [v8].[Discriminator] IN (N'PoweredVehicle', N'CompositeVehicle') ) AS [t5] ON [v7].[Name] = [t5].[Name] - WHERE [v7].[FuelTank_Discriminator] IS NOT NULL + WHERE [v7].[Capacity] IS NOT NULL AND [v7].[FuelTank_Discriminator] IS NOT NULL UNION SELECT [v9].[Name], [v9].[Capacity], [v9].[FuelTank_Discriminator], [v9].[FuelType], [v9].[GrainGeometry] FROM [Vehicles] AS [v9] @@ -73,7 +73,7 @@ WHERE [v11].[Discriminator] IN (N'PoweredVehicle', N'CompositeVehicle') ) AS [t7] ON [v10].[Name] = [t7].[Name] WHERE [v10].[Engine_Discriminator] IN (N'ContinuousCombustionEngine', N'IntermittentCombustionEngine', N'SolidRocket') ) AS [t6] ON [v9].[Name] = [t6].[Name] - WHERE [v9].[FuelTank_Discriminator] IS NOT NULL + WHERE [v9].[Capacity] IS NOT NULL AND [v9].[FuelTank_Discriminator] IS NOT NULL ) AS [t4] ON [t2].[Name] = [t4].[Name] ORDER BY [v].[Name]"); } @@ -120,7 +120,7 @@ INNER JOIN ( FROM [Vehicles] AS [v0] WHERE [v0].[Discriminator] IN (N'PoweredVehicle', N'CompositeVehicle') ) AS [t] ON [v].[Name] = [t].[Name] -WHERE [v].[FuelTank_Discriminator] IS NOT NULL +WHERE [v].[Capacity] IS NOT NULL AND [v].[FuelTank_Discriminator] IS NOT NULL UNION SELECT [v1].[Name], [v1].[Capacity], [v1].[FuelTank_Discriminator], [v1].[FuelType], [v1].[GrainGeometry] FROM [Vehicles] AS [v1] @@ -134,7 +134,7 @@ WHERE [v3].[Discriminator] IN (N'PoweredVehicle', N'CompositeVehicle') ) AS [t1] ON [v2].[Name] = [t1].[Name] WHERE [v2].[Engine_Discriminator] IN (N'ContinuousCombustionEngine', N'IntermittentCombustionEngine', N'SolidRocket') ) AS [t0] ON [v1].[Name] = [t0].[Name] -WHERE [v1].[FuelTank_Discriminator] IS NOT NULL"); +WHERE [v1].[Capacity] IS NOT NULL AND [v1].[FuelTank_Discriminator] IS NOT NULL"); } public override async Task Can_query_shared_derived_nonhierarchy() @@ -149,7 +149,7 @@ INNER JOIN ( FROM [Vehicles] AS [v0] WHERE [v0].[Discriminator] IN (N'PoweredVehicle', N'CompositeVehicle') ) AS [t] ON [v].[Name] = [t].[Name] -WHERE [v].[Capacity] IS NOT NULL OR [v].[FuelType] IS NOT NULL +WHERE [v].[Capacity] IS NOT NULL UNION SELECT [v1].[Name], [v1].[Capacity], [v1].[FuelType] FROM [Vehicles] AS [v1] @@ -163,7 +163,7 @@ WHERE [v3].[Discriminator] IN (N'PoweredVehicle', N'CompositeVehicle') ) AS [t1] ON [v2].[Name] = [t1].[Name] WHERE [v2].[Engine_Discriminator] IN (N'ContinuousCombustionEngine', N'IntermittentCombustionEngine', N'SolidRocket') ) AS [t0] ON [v1].[Name] = [t0].[Name] -WHERE [v1].[Capacity] IS NOT NULL OR [v1].[FuelType] IS NOT NULL"); +WHERE [v1].[Capacity] IS NOT NULL"); } public override async Task Can_query_shared_derived_nonhierarchy_all_required() @@ -248,7 +248,7 @@ public override async Task Optional_dependent_materialized_when_no_properties() await base.Optional_dependent_materialized_when_no_properties(); AssertSql( - @"SELECT TOP(1) [v].[Name], [v].[Discriminator], [v].[SeatingCapacity], [v].[AttachedVehicleName], [t].[Name], [t].[Operator_Discriminator], [t].[Operator_Name], [t].[LicenseType], [t0].[Name], [t0].[Type] + @"SELECT TOP(1) [v].[Name], [v].[Discriminator], [v].[SeatingCapacity], [v].[AttachedVehicleName], [t].[Name], [t].[Operator_Discriminator], [t].[Operator_Name], [t].[LicenseType], [t0].[Name], [t0].[Active], [t0].[Type] FROM [Vehicles] AS [v] LEFT JOIN ( SELECT [v0].[Name], [v0].[Operator_Discriminator], [v0].[Operator_Name], [v0].[LicenseType] @@ -256,14 +256,14 @@ FROM [Vehicles] AS [v0] INNER JOIN [Vehicles] AS [v1] ON [v0].[Name] = [v1].[Name] ) AS [t] ON [v].[Name] = [t].[Name] LEFT JOIN ( - SELECT [v2].[Name], [v2].[Type] + SELECT [v2].[Name], [v2].[Active], [v2].[Type] FROM [Vehicles] AS [v2] INNER JOIN ( SELECT [v3].[Name] FROM [Vehicles] AS [v3] INNER JOIN [Vehicles] AS [v4] ON [v3].[Name] = [v4].[Name] ) AS [t1] ON [v2].[Name] = [t1].[Name] - WHERE [v2].[Type] IS NOT NULL + WHERE [v2].[Active] IS NOT NULL ) AS [t0] ON [t].[Name] = [t0].[Name] WHERE [v].[Name] = N'AIM-9M Sidewinder' ORDER BY [v].[Name]"); diff --git a/test/EFCore.Sqlite.FunctionalTests/DataAnnotationSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/DataAnnotationSqliteTest.cs index 8aa44672ed6..4c77d00b7e3 100644 --- a/test/EFCore.Sqlite.FunctionalTests/DataAnnotationSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/DataAnnotationSqliteTest.cs @@ -96,12 +96,12 @@ public override void ConcurrencyCheckAttribute_throws_if_value_in_database_chang base.ConcurrencyCheckAttribute_throws_if_value_in_database_changed(); AssertSql( - @"SELECT ""s"".""Unique_No"", ""s"".""MaxLengthProperty"", ""s"".""Name"", ""s"".""RowVersion"", ""s"".""AdditionalDetails_Name"", ""s"".""Details_Name"" + @"SELECT ""s"".""Unique_No"", ""s"".""MaxLengthProperty"", ""s"".""Name"", ""s"".""RowVersion"", ""s"".""AdditionalDetails_Name"", ""s"".""AdditionalDetails_Value"", ""s"".""Details_Name"", ""s"".""Details_Value"" FROM ""Sample"" AS ""s"" WHERE ""s"".""Unique_No"" = 1 LIMIT 1", // - @"SELECT ""s"".""Unique_No"", ""s"".""MaxLengthProperty"", ""s"".""Name"", ""s"".""RowVersion"", ""s"".""AdditionalDetails_Name"", ""s"".""Details_Name"" + @"SELECT ""s"".""Unique_No"", ""s"".""MaxLengthProperty"", ""s"".""Name"", ""s"".""RowVersion"", ""s"".""AdditionalDetails_Name"", ""s"".""AdditionalDetails_Value"", ""s"".""Details_Name"", ""s"".""Details_Value"" FROM ""Sample"" AS ""s"" WHERE ""s"".""Unique_No"" = 1 LIMIT 1", @@ -134,10 +134,12 @@ public override void DatabaseGeneratedAttribute_autogenerates_values_when_set_to @p1='Third' (Nullable = false) (Size = 5) @p2='00000000-0000-0000-0000-000000000003' (DbType = String) @p3='Third Additional Name' (Size = 21) -@p4='Third Name' (Size = 10) +@p4='0' (Nullable = true) (DbType = String) +@p5='Third Name' (Size = 10) +@p6='0' (Nullable = true) (DbType = String) -INSERT INTO ""Sample"" (""MaxLengthProperty"", ""Name"", ""RowVersion"", ""AdditionalDetails_Name"", ""Details_Name"") -VALUES (@p0, @p1, @p2, @p3, @p4); +INSERT INTO ""Sample"" (""MaxLengthProperty"", ""Name"", ""RowVersion"", ""AdditionalDetails_Name"", ""AdditionalDetails_Value"", ""Details_Name"", ""Details_Value"") +VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6); SELECT ""Unique_No"" FROM ""Sample"" WHERE changes() = 1 AND ""rowid"" = last_insert_rowid();");