Skip to content

Commit bf21ca5

Browse files
authored
Preserve unicodeness and fixed-lengthiness in compiled model. (#32662)
Fixes #32617
1 parent cac4f4f commit bf21ca5

File tree

35 files changed

+652
-284
lines changed

35 files changed

+652
-284
lines changed

src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs

-2
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ public virtual void Initialize(IDbContextOptions options)
169169
Region = cosmosOptions.Region;
170170
PreferredRegions = cosmosOptions.PreferredRegions;
171171
LimitToEndpoint = cosmosOptions.LimitToEndpoint;
172-
EnableContentResponseOnWrite = cosmosOptions.EnableContentResponseOnWrite;
173172
ConnectionMode = cosmosOptions.ConnectionMode;
174173
WebProxy = cosmosOptions.WebProxy;
175174
RequestTimeout = cosmosOptions.RequestTimeout;
@@ -208,7 +207,6 @@ public virtual void Validate(IDbContextOptions options)
208207
|| GatewayModeMaxConnectionLimit != cosmosOptions.GatewayModeMaxConnectionLimit
209208
|| MaxTcpConnectionsPerEndpoint != cosmosOptions.MaxTcpConnectionsPerEndpoint
210209
|| MaxRequestsPerTcpConnection != cosmosOptions.MaxRequestsPerTcpConnection
211-
|| EnableContentResponseOnWrite != cosmosOptions.EnableContentResponseOnWrite
212210
|| HttpClientFactory != cosmosOptions.HttpClientFactory
213211
))
214212
{

src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs

+21-1
Original file line numberDiff line numberDiff line change
@@ -2154,7 +2154,15 @@ public override bool Create(
21542154
&& relationalTypeMapping.Scale != defaultInstance.Scale;
21552155
var dbTypeDifferent = relationalTypeMapping.DbType != null
21562156
&& relationalTypeMapping.DbType != defaultInstance.DbType;
2157-
if (storeTypeDifferent || sizeDifferent || precisionDifferent || scaleDifferent || dbTypeDifferent)
2157+
var isUnicodeDifferent = relationalTypeMapping.IsUnicode != defaultInstance.IsUnicode;
2158+
var isFixedLengthDifferent = relationalTypeMapping.IsFixedLength != defaultInstance.IsFixedLength;
2159+
if (storeTypeDifferent
2160+
|| sizeDifferent
2161+
|| precisionDifferent
2162+
|| scaleDifferent
2163+
|| dbTypeDifferent
2164+
|| isUnicodeDifferent
2165+
|| isFixedLengthDifferent)
21582166
{
21592167
AddNamespace(typeof(RelationalTypeMappingInfo), parameters.Namespaces);
21602168
mainBuilder.AppendLine(",")
@@ -2174,6 +2182,18 @@ public override bool Create(
21742182
"size", code.Literal(relationalTypeMapping.Size), mainBuilder, ref firstParameter);
21752183
}
21762184

2185+
if (isUnicodeDifferent)
2186+
{
2187+
GenerateArgument(
2188+
"unicode", code.Literal(relationalTypeMapping.IsUnicode), mainBuilder, ref firstParameter);
2189+
}
2190+
2191+
if (isFixedLengthDifferent)
2192+
{
2193+
GenerateArgument(
2194+
"fixedLength", code.Literal(relationalTypeMapping.IsFixedLength), mainBuilder, ref firstParameter);
2195+
}
2196+
21772197
if (precisionDifferent)
21782198
{
21792199
GenerateArgument(

src/EFCore.SqlServer/Storage/Internal/SqlServerStringTypeMapping.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ public SqlServerStringTypeMapping(
6868
private static string GetDefaultStoreName(bool unicode, bool fixedLength)
6969
=> unicode
7070
? fixedLength ? "nchar" : "nvarchar"
71-
: fixedLength
72-
? "char"
73-
: "varchar";
71+
: fixedLength ? "char" : "varchar";
7472

7573
private static DbType? GetDbType(bool unicode, bool fixedLength)
7674
=> unicode

test/EFCore.Cosmos.FunctionalTests/CosmosConcurrencyTest.cs

+9-86
Original file line numberDiff line numberDiff line change
@@ -45,91 +45,21 @@ public virtual Task Updating_then_updating_the_same_entity_results_in_DbUpdateCo
4545
ctx => ctx.Customers.Single(c => c.Id == "3").Name = "Updated",
4646
ctx => ctx.Customers.Single(c => c.Id == "3").Name = "Updated");
4747

48-
[ConditionalFact]
49-
public async Task Etag_will_return_when_content_response_enabled_false()
50-
{
51-
await using var testDatabase = CosmosTestStore.CreateInitialized(
52-
DatabaseName,
53-
o => o.ContentResponseOnWriteEnabled(false));
54-
55-
var customer = new Customer
56-
{
57-
Id = "4", Name = "Theon",
58-
};
59-
60-
await using (var context = new ConcurrencyContext(CreateOptions(testDatabase)))
61-
{
62-
await context.Database.EnsureCreatedAsync();
63-
64-
await context.AddAsync(customer);
65-
66-
await context.SaveChangesAsync();
67-
}
68-
69-
await using (var context = new ConcurrencyContext(CreateOptions(testDatabase)))
70-
{
71-
var customerFromStore = await context.Set<Customer>().SingleAsync();
72-
73-
Assert.Equal(customer.Id, customerFromStore.Id);
74-
Assert.Equal("Theon", customerFromStore.Name);
75-
Assert.Equal(customer.ETag, customerFromStore.ETag);
76-
77-
context.Remove(customerFromStore);
78-
79-
await context.SaveChangesAsync();
80-
}
81-
}
82-
83-
[ConditionalFact]
84-
public async Task Etag_will_return_when_content_response_enabled_true()
85-
{
86-
await using var testDatabase = CosmosTestStore.CreateInitialized(
87-
DatabaseName,
88-
o => o.ContentResponseOnWriteEnabled());
89-
90-
var customer = new Customer
91-
{
92-
Id = "3", Name = "Theon",
93-
};
94-
95-
await using (var context = new ConcurrencyContext(CreateOptions(testDatabase)))
96-
{
97-
await context.Database.EnsureCreatedAsync();
98-
99-
await context.AddAsync(customer);
100-
101-
await context.SaveChangesAsync();
102-
}
103-
104-
await using (var context = new ConcurrencyContext(CreateOptions(testDatabase)))
105-
{
106-
var customerFromStore = await context.Set<Customer>().SingleAsync();
107-
108-
Assert.Equal(customer.Id, customerFromStore.Id);
109-
Assert.Equal("Theon", customerFromStore.Name);
110-
Assert.Equal(customer.ETag, customerFromStore.ETag);
111-
112-
context.Remove(customerFromStore);
113-
114-
await context.SaveChangesAsync();
115-
}
116-
}
117-
11848
[ConditionalTheory]
11949
[InlineData(null)]
12050
[InlineData(true)]
12151
[InlineData(false)]
12252
public async Task Etag_is_updated_in_entity_after_SaveChanges(bool? contentResponseOnWriteEnabled)
12353
{
124-
await using var testDatabase = CosmosTestStore.CreateInitialized(
125-
DatabaseName,
126-
o =>
54+
var options = new DbContextOptionsBuilder(Fixture.CreateOptions())
55+
.UseCosmos(o =>
12756
{
128-
if (contentResponseOnWriteEnabled.HasValue)
57+
if (contentResponseOnWriteEnabled != null)
12958
{
13059
o.ContentResponseOnWriteEnabled(contentResponseOnWriteEnabled.Value);
13160
}
132-
});
61+
})
62+
.Options;
13363

13464
var customer = new Customer
13565
{
@@ -139,10 +69,9 @@ public async Task Etag_is_updated_in_entity_after_SaveChanges(bool? contentRespo
13969
};
14070

14171
string etag = null;
142-
143-
await using (var context = new ConcurrencyContext(CreateOptions(testDatabase)))
72+
await using (var context = new ConcurrencyContext(options))
14473
{
145-
await context.Database.EnsureCreatedAsync();
74+
await Fixture.TestStore.CleanAsync(context);
14675

14776
await context.AddAsync(customer);
14877

@@ -151,7 +80,7 @@ public async Task Etag_is_updated_in_entity_after_SaveChanges(bool? contentRespo
15180
etag = customer.ETag;
15281
}
15382

154-
await using (var context = new ConcurrencyContext(CreateOptions(testDatabase)))
83+
await using (var context = new ConcurrencyContext(options))
15584
{
15685
var customerFromStore = await context.Set<Customer>().SingleAsync();
15786

@@ -208,7 +137,7 @@ protected virtual async Task ConcurrencyTestAsync<TException>(
208137
where TException : DbUpdateException
209138
{
210139
using var outerContext = CreateContext();
211-
await outerContext.Database.EnsureCreatedAsync();
140+
await Fixture.TestStore.CleanAsync(outerContext);
212141
seedAction?.Invoke(outerContext);
213142
await outerContext.SaveChangesAsync();
214143

@@ -258,12 +187,6 @@ protected override void OnModelCreating(ModelBuilder builder)
258187
});
259188
}
260189

261-
private DbContextOptions CreateOptions(CosmosTestStore testDatabase)
262-
=> testDatabase.AddProviderOptions(new DbContextOptionsBuilder())
263-
.ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))
264-
.EnableDetailedErrors()
265-
.Options;
266-
267190
public class Customer
268191
{
269192
public string Id { get; set; }

test/EFCore.Cosmos.FunctionalTests/MaterializationInterceptionCosmosTest.cs

+4-24
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,9 @@
44
namespace Microsoft.EntityFrameworkCore;
55

66
public class MaterializationInterceptionCosmosTest :
7-
MaterializationInterceptionTestBase<MaterializationInterceptionCosmosTest.CosmosLibraryContext>,
8-
IClassFixture<MaterializationInterceptionCosmosTest.MaterializationInterceptionCosmosFixture>
7+
MaterializationInterceptionTestBase<MaterializationInterceptionCosmosTest.CosmosLibraryContext>
98
{
10-
public MaterializationInterceptionCosmosTest(MaterializationInterceptionCosmosFixture fixture)
11-
: base(fixture)
12-
{
13-
}
14-
15-
public override Task Intercept_query_materialization_with_owned_types_projecting_collection(bool async)
9+
public override Task Intercept_query_materialization_with_owned_types_projecting_collection(bool async, bool usePooling)
1610
=> Task.CompletedTask;
1711

1812
public class CosmosLibraryContext : LibraryContext
@@ -30,20 +24,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
3024
}
3125
}
3226

33-
public override LibraryContext CreateContext(IEnumerable<ISingletonInterceptor> interceptors, bool inject)
34-
=> new CosmosLibraryContext(Fixture.CreateOptions(interceptors, inject));
35-
36-
public class MaterializationInterceptionCosmosFixture : SingletonInterceptorsFixtureBase
37-
{
38-
protected override string StoreName
39-
=> "MaterializationInterception";
40-
41-
protected override ITestStoreFactory TestStoreFactory
42-
=> CosmosTestStoreFactory.Instance;
43-
44-
protected override IServiceCollection InjectInterceptors(
45-
IServiceCollection serviceCollection,
46-
IEnumerable<ISingletonInterceptor> injectedInterceptors)
47-
=> base.InjectInterceptors(serviceCollection.AddEntityFrameworkCosmos(), injectedInterceptors);
48-
}
27+
protected override ITestStoreFactory TestStoreFactory
28+
=> CosmosTestStoreFactory.Instance;
4929
}

test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStoreFactory.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ protected CosmosTestStoreFactory()
1414
public IServiceCollection AddProviderServices(IServiceCollection serviceCollection)
1515
=> serviceCollection
1616
.AddEntityFrameworkCosmos()
17-
.AddSingleton<ILoggerFactory>(new TestSqlLoggerFactory())
18-
.AddSingleton<TestStoreIndex>();
17+
.AddSingleton<ILoggerFactory>(new TestSqlLoggerFactory());
1918

2019
public TestStore Create(string storeName)
2120
=> CosmosTestStore.Create(storeName);

test/EFCore.InMemory.FunctionalTests/MaterializationInterceptionInMemoryTest.cs

+5-25
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,8 @@
66
namespace Microsoft.EntityFrameworkCore;
77

88
public class MaterializationInterceptionInMemoryTest :
9-
MaterializationInterceptionTestBase<MaterializationInterceptionInMemoryTest.InMemoryLibraryContext>,
10-
IClassFixture<MaterializationInterceptionInMemoryTest.MaterializationInterceptionInMemoryFixture>
9+
MaterializationInterceptionTestBase<MaterializationInterceptionInMemoryTest.InMemoryLibraryContext>
1110
{
12-
public MaterializationInterceptionInMemoryTest(MaterializationInterceptionInMemoryFixture fixture)
13-
: base(fixture)
14-
{
15-
}
16-
1711
public class InMemoryLibraryContext : LibraryContext
1812
{
1913
public InMemoryLibraryContext(DbContextOptions options)
@@ -29,23 +23,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
2923
}
3024
}
3125

32-
public override LibraryContext CreateContext(IEnumerable<ISingletonInterceptor> interceptors, bool inject)
33-
=> new InMemoryLibraryContext(Fixture.CreateOptions(interceptors, inject));
34-
35-
public class MaterializationInterceptionInMemoryFixture : SingletonInterceptorsFixtureBase
36-
{
37-
protected override string StoreName
38-
=> "MaterializationInterception";
39-
40-
protected override ITestStoreFactory TestStoreFactory
41-
=> InMemoryTestStoreFactory.Instance;
26+
protected override ITestStoreFactory TestStoreFactory
27+
=> InMemoryTestStoreFactory.Instance;
4228

43-
protected override IServiceCollection InjectInterceptors(
44-
IServiceCollection serviceCollection,
45-
IEnumerable<ISingletonInterceptor> injectedInterceptors)
46-
=> base.InjectInterceptors(serviceCollection.AddEntityFrameworkInMemoryDatabase(), injectedInterceptors);
47-
48-
public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
49-
=> base.AddOptions(builder).ConfigureWarnings(c => c.Ignore(InMemoryEventId.TransactionIgnoredWarning));
50-
}
29+
protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
30+
=> base.AddOptions(builder).ConfigureWarnings(c => c.Ignore(InMemoryEventId.TransactionIgnoredWarning));
5131
}

test/EFCore.InMemory.FunctionalTests/TestUtilities/InMemoryTestStore.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public InMemoryTestStore InitializeInMemory(
3939
protected override TestStoreIndex GetTestStoreIndex(IServiceProvider serviceProvider)
4040
=> serviceProvider == null
4141
? base.GetTestStoreIndex(null)
42-
: serviceProvider.GetRequiredService<TestStoreIndex>();
42+
: serviceProvider.GetService<TestStoreIndex>() ?? base.GetTestStoreIndex(serviceProvider);
4343

4444
public override DbContextOptionsBuilder AddProviderOptions(DbContextOptionsBuilder builder)
4545
=> builder.UseInMemoryDatabase(Name);

0 commit comments

Comments
 (0)