From 4eadee29c64e9e2b730444378ee9ee5dbeb220aa Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 23 Oct 2019 17:21:24 +0800 Subject: [PATCH 1/5] Added DataTimeValueConverters function. Resolve #1983 --- .../Abp/EntityFrameworkCore/AbpDbContext.cs | 43 +++++++++++++++ .../AbpDateTimeValueConverter.cs | 17 ++++++ .../AbpDateTimeValueConverter_Tests.cs | 9 ++++ .../Volo/Abp/TestApp/Domain/Person.cs | 6 +++ .../AbpDateTimeValueConverter_Tests.cs | 53 +++++++++++++++++++ 5 files changed, 128 insertions(+) create mode 100644 framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpDateTimeValueConverter.cs create mode 100644 framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpDateTimeValueConverter_Tests.cs create mode 100644 framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index 3d4b45d75d..9064ddc2ba 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -18,10 +18,12 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.EntityFrameworkCore.EntityHistory; +using Volo.Abp.EntityFrameworkCore.ValueConverters; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; using Volo.Abp.Reflection; using Volo.Abp.Threading; +using Volo.Abp.Timing; namespace Volo.Abp.EntityFrameworkCore { @@ -48,6 +50,8 @@ namespace Volo.Abp.EntityFrameworkCore public IAuditingManager AuditingManager { get; set; } + public IClock Clock { get; set; } + public ILogger> Logger { get; set; } private static readonly MethodInfo ConfigureBasePropertiesMethodInfo @@ -57,6 +61,13 @@ namespace Volo.Abp.EntityFrameworkCore BindingFlags.Instance | BindingFlags.NonPublic ); + private static readonly MethodInfo ConfigureValueConverterMethodInfo + = typeof(AbpDbContext) + .GetMethod( + nameof(ConfigureValueConverter), + BindingFlags.Instance | BindingFlags.NonPublic + ); + protected AbpDbContext(DbContextOptions options) : base(options) { @@ -75,6 +86,10 @@ namespace Volo.Abp.EntityFrameworkCore ConfigureBasePropertiesMethodInfo .MakeGenericMethod(entityType.ClrType) .Invoke(this, new object[] { modelBuilder, entityType }); + + ConfigureValueConverterMethodInfo + .MakeGenericMethod(entityType.ClrType) + .Invoke(this, new object[] { modelBuilder, entityType }); } } @@ -488,6 +503,34 @@ namespace Volo.Abp.EntityFrameworkCore } } + protected virtual void ConfigureValueConverter(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) + where TEntity : class + { + if (mutableEntityType.BaseType == null && + !typeof(TEntity).IsDefined(typeof(DisableDateTimeNormalizationAttribute), true) && + !typeof(TEntity).IsDefined(typeof(OwnedAttribute), true) && + !mutableEntityType.IsOwned()) + { + var dateTimeValueConverter = new AbpDateTimeValueConverter(Clock); + + var dateTimePropertyInfos = typeof(TEntity).GetProperties() + .Where(property => + (property.PropertyType == typeof(DateTime) || + property.PropertyType == typeof(DateTime?)) && + property.CanWrite && + !property.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true) + ).ToList(); + + dateTimePropertyInfos.ForEach(property => + { + modelBuilder + .Entity() + .Property(property.Name) + .HasConversion(dateTimeValueConverter); + }); + } + } + protected virtual bool ShouldFilterEntity(IMutableEntityType entityType) where TEntity : class { if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity))) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpDateTimeValueConverter.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpDateTimeValueConverter.cs new file mode 100644 index 0000000000..e3562c4134 --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpDateTimeValueConverter.cs @@ -0,0 +1,17 @@ +using System; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.Timing; + +namespace Volo.Abp.EntityFrameworkCore.ValueConverters +{ + public class AbpDateTimeValueConverter : ValueConverter + { + public AbpDateTimeValueConverter(IClock clock, [CanBeNull] ConverterMappingHints mappingHints = null) + : base( + x => x.HasValue ? clock.Normalize(x.Value) : x, + x => x.HasValue ? clock.Normalize(x.Value) : x, mappingHints) + { + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpDateTimeValueConverter_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpDateTimeValueConverter_Tests.cs new file mode 100644 index 0000000000..c2793b3b67 --- /dev/null +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/ValueConverters/AbpDateTimeValueConverter_Tests.cs @@ -0,0 +1,9 @@ +using Volo.Abp.TestApp.Testing; + +namespace Volo.Abp.EntityFrameworkCore.ValueConverters +{ + public class AbpDateTimeValueConverter_Tests : AbpDateTimeValueConverter_Tests + { + + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs index 3bbec118a2..9075740f11 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs @@ -2,6 +2,7 @@ using System; using System.Collections.ObjectModel; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; +using Volo.Abp.Timing; namespace Volo.Abp.TestApp.Domain { @@ -15,6 +16,11 @@ namespace Volo.Abp.TestApp.Domain public virtual int Age { get; set; } + public virtual DateTime? Birthday { get; set; } + + [DisableDateTimeNormalization] + public virtual DateTime? LastActive { get; set; } + public virtual Collection Phones { get; set; } private Person() diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs new file mode 100644 index 0000000000..cbeef807cb --- /dev/null +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs @@ -0,0 +1,53 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Modularity; +using Volo.Abp.TestApp.Domain; +using Volo.Abp.Timing; +using Xunit; + +namespace Volo.Abp.TestApp.Testing +{ + public abstract class AbpDateTimeValueConverter_Tests : TestAppTestBase + where TStartupModule : IAbpModule + { + private readonly IBasicRepository _personRepository; + + protected AbpDateTimeValueConverter_Tests() + { + _personRepository = GetRequiredService>(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + services.Configure(options => options.Kind = DateTimeKind.Utc); + } + + [Fact] + public async Task DateTime_Kind_Should_Be_Normalized_To_UTC_Test() + { + var personId = Guid.Parse("4125582e-d100-4c27-aa84-e4de85830dca"); + await _personRepository.InsertAsync(new Person(personId, "bob lee", 18) + { + Birthday = DateTime.Parse("2020-01-01 00:00:00"), + LastActive = DateTime.Parse("2020-01-01 00:00:00"), + }, true); + + var person = await _personRepository.GetAsync(personId); + + person.ShouldNotBeNull(); + person.CreationTime.Kind.ShouldBe(DateTimeKind.Utc); + + person.Birthday.ShouldNotBeNull(); + person.Birthday.Value.Kind.ShouldBe(DateTimeKind.Utc); + person.Birthday.Value.ToString("yyy-MM-dd HH:mm:ss").ShouldBe("2020-01-01 00:00:00"); + + //LastActive DisableDateTimeNormalization + person.LastActive.ShouldNotBeNull(); + person.LastActive.Value.Kind.ShouldBe(DateTimeKind.Unspecified); + person.LastActive.Value.ToString("yyy-MM-dd HH:mm:ss").ShouldBe("2020-01-01 00:00:00"); + } + } +} \ No newline at end of file From a898b4abe8135812aea6069c2f32fb33baf182c3 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 23 Oct 2019 18:09:49 +0800 Subject: [PATCH 2/5] Handling Clock in AbpDbContext may be null. --- .../Volo/Abp/EntityFrameworkCore/AbpDbContext.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index 9064ddc2ba..aa91755f5d 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; @@ -511,6 +511,11 @@ namespace Volo.Abp.EntityFrameworkCore !typeof(TEntity).IsDefined(typeof(OwnedAttribute), true) && !mutableEntityType.IsOwned()) { + if (Clock == null) + { + return; + } + var dateTimeValueConverter = new AbpDateTimeValueConverter(Clock); var dateTimePropertyInfos = typeof(TEntity).GetProperties() From 91ba0f2594c83d00e2a8c35aea82579ed862f570 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 23 Oct 2019 20:50:26 +0800 Subject: [PATCH 3/5] Configuring AbpClockOptions in AbpEntityFrameworkCoreTestModule. --- .../Volo/Abp/EntityFrameworkCore/AbpDbContext.cs | 2 +- .../EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs | 6 +++++- .../Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs | 5 ----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index aa91755f5d..b42a2cfc66 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -511,7 +511,7 @@ namespace Volo.Abp.EntityFrameworkCore !typeof(TEntity).IsDefined(typeof(OwnedAttribute), true) && !mutableEntityType.IsOwned()) { - if (Clock == null) + if (Clock == null || !Clock.SupportsMultipleTimezone) { return; } diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs index b1b92ab5b2..85eb1119d5 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs @@ -1,4 +1,5 @@ -using Microsoft.Data.Sqlite; +using System; +using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; @@ -10,6 +11,7 @@ using Volo.Abp.Modularity; using Volo.Abp.TestApp; using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.EntityFrameworkCore; +using Volo.Abp.Timing; namespace Volo.Abp.EntityFrameworkCore { @@ -41,6 +43,8 @@ namespace Volo.Abp.EntityFrameworkCore abpDbContextConfigurationContext.DbContextOptions.UseSqlite(sqliteConnection); }); }); + + Configure(options => options.Kind = DateTimeKind.Utc); } public override void OnPreApplicationInitialization(ApplicationInitializationContext context) diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs index cbeef807cb..6b0caaa7b6 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs @@ -20,11 +20,6 @@ namespace Volo.Abp.TestApp.Testing _personRepository = GetRequiredService>(); } - protected override void AfterAddApplication(IServiceCollection services) - { - services.Configure(options => options.Kind = DateTimeKind.Utc); - } - [Fact] public async Task DateTime_Kind_Should_Be_Normalized_To_UTC_Test() { From b4940f135cf6cb122b12267f0a693b11807865d0 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 10 Nov 2019 14:28:06 +0800 Subject: [PATCH 4/5] Added Keyless Entity Types unit test. https://docs.microsoft.com/en-us/ef/core/modeling/keyless-entity-types --- .../AbpEntityFrameworkCoreTestModule.cs | 3 ++ .../EntityFrameworkCore/PersonRepository.cs | 24 +++++++++++++++ .../EntityFrameworkCore/TestAppDbContext.cs | 9 ++++++ .../Abp/TestApp/Domain/IPersonRepository.cs | 13 +++++++++ .../Volo/Abp/TestApp/Domain/PersonView.cs | 19 ++++++++++++ .../AbpDateTimeValueConverter_Tests.cs | 29 +++++++++++++++++-- 6 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs create mode 100644 framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/IPersonRepository.cs create mode 100644 framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonView.cs diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs index 85eb1119d5..8925c2bff3 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs @@ -60,6 +60,9 @@ namespace Volo.Abp.EntityFrameworkCore using (var context = new TestMigrationsDbContext(new DbContextOptionsBuilder().UseSqlite(connection).Options)) { context.GetService().CreateTables(); + context.Database.ExecuteSqlRaw( + @"CREATE VIEW View_PersonView AS + SELECT Id, Name, CreationTime, Birthday, LastActive FROM People"); } return connection; diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs new file mode 100644 index 0000000000..e42d88c2b8 --- /dev/null +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.TestApp.Domain; + +namespace Volo.Abp.TestApp.EntityFrameworkCore +{ + public class PersonRepository : EfCoreRepository, IPersonRepository + { + public PersonRepository(IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public async Task GetViewAsync(Guid id) + { + return await DbContext.PersonView.Where(x => x.Id == id).FirstOrDefaultAsync(); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs index bfcecdeb65..5e243b9a03 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs @@ -11,6 +11,8 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore public DbSet Cities { get; set; } + public DbSet PersonView { get; set; } + public DbSet DummyEntities { get; set; } public DbSet EntityWithIntPks { get; set; } @@ -29,6 +31,13 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore { b.HasKey(p => new {p.PersonId, p.Number}); }); + + modelBuilder + .Entity(p => + { + p.HasNoKey(); + p.ToView("View_PersonView"); + }); } } } diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/IPersonRepository.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/IPersonRepository.cs new file mode 100644 index 0000000000..ac094de826 --- /dev/null +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/IPersonRepository.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.TestApp.Domain +{ + public interface IPersonRepository : IBasicRepository + { + Task GetViewAsync(Guid id); + } +} diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonView.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonView.cs new file mode 100644 index 0000000000..72249fa541 --- /dev/null +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonView.cs @@ -0,0 +1,19 @@ +using System; +using Volo.Abp.Timing; + +namespace Volo.Abp.TestApp.Domain +{ + public class PersonView + { + public Guid Id { get; set; } + + public string Name { get; set; } + + public DateTime CreationTime { get; set; } + + public DateTime? Birthday { get; set; } + + [DisableDateTimeNormalization] + public DateTime? LastActive { get; set; } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs index 6b0caaa7b6..bf95982daa 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs @@ -13,11 +13,11 @@ namespace Volo.Abp.TestApp.Testing public abstract class AbpDateTimeValueConverter_Tests : TestAppTestBase where TStartupModule : IAbpModule { - private readonly IBasicRepository _personRepository; + private readonly IPersonRepository _personRepository; protected AbpDateTimeValueConverter_Tests() { - _personRepository = GetRequiredService>(); + _personRepository = GetRequiredService(); } [Fact] @@ -44,5 +44,30 @@ namespace Volo.Abp.TestApp.Testing person.LastActive.Value.Kind.ShouldBe(DateTimeKind.Unspecified); person.LastActive.Value.ToString("yyy-MM-dd HH:mm:ss").ShouldBe("2020-01-01 00:00:00"); } + + [Fact] + public async Task DateTime_Kind_Should_Be_Normalized_To_UTC_View_Test() + { + var personId = Guid.Parse("7a942bca-c911-4473-93aa-2daf88e18fb9"); + await _personRepository.InsertAsync(new Person(personId, "bob lee", 18) + { + Birthday = DateTime.Parse("2020-01-01 00:00:00"), + LastActive = DateTime.Parse("2020-01-01 00:00:00"), + }, true); + + var person = await _personRepository.GetViewAsync(personId); + + person.ShouldNotBeNull(); + person.CreationTime.Kind.ShouldBe(DateTimeKind.Utc); + + person.Birthday.ShouldNotBeNull(); + person.Birthday.Value.Kind.ShouldBe(DateTimeKind.Utc); + person.Birthday.Value.ToString("yyy-MM-dd HH:mm:ss").ShouldBe("2020-01-01 00:00:00"); + + //LastActive DisableDateTimeNormalization + person.LastActive.ShouldNotBeNull(); + person.LastActive.Value.Kind.ShouldBe(DateTimeKind.Unspecified); + person.LastActive.Value.ToString("yyy-MM-dd HH:mm:ss").ShouldBe("2020-01-01 00:00:00"); + } } } \ No newline at end of file From 6944da4a8200b6f6b26a7601f9569d2a28eba677 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 10 Nov 2019 14:38:52 +0800 Subject: [PATCH 5/5] Remove the id property from the view. --- .../EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs | 2 +- .../Abp/TestApp/EntityFrameworkCore/PersonRepository.cs | 4 ++-- .../Volo/Abp/TestApp/Domain/IPersonRepository.cs | 2 +- .../Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonView.cs | 2 -- .../Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs | 6 +++--- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs index 8925c2bff3..71522d0216 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs @@ -62,7 +62,7 @@ namespace Volo.Abp.EntityFrameworkCore context.GetService().CreateTables(); context.Database.ExecuteSqlRaw( @"CREATE VIEW View_PersonView AS - SELECT Id, Name, CreationTime, Birthday, LastActive FROM People"); + SELECT Name, CreationTime, Birthday, LastActive FROM People"); } return connection; diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs index e42d88c2b8..ab8c1920a7 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs @@ -16,9 +16,9 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore { } - public async Task GetViewAsync(Guid id) + public async Task GetViewAsync(string name) { - return await DbContext.PersonView.Where(x => x.Id == id).FirstOrDefaultAsync(); + return await DbContext.PersonView.Where(x => x.Name == name).FirstOrDefaultAsync(); } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/IPersonRepository.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/IPersonRepository.cs index ac094de826..9058522346 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/IPersonRepository.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/IPersonRepository.cs @@ -8,6 +8,6 @@ namespace Volo.Abp.TestApp.Domain { public interface IPersonRepository : IBasicRepository { - Task GetViewAsync(Guid id); + Task GetViewAsync(string name); } } diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonView.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonView.cs index 72249fa541..e77827c263 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonView.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/PersonView.cs @@ -5,8 +5,6 @@ namespace Volo.Abp.TestApp.Domain { public class PersonView { - public Guid Id { get; set; } - public string Name { get; set; } public DateTime CreationTime { get; set; } diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs index bf95982daa..e36225e53c 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/AbpDateTimeValueConverter_Tests.cs @@ -48,14 +48,14 @@ namespace Volo.Abp.TestApp.Testing [Fact] public async Task DateTime_Kind_Should_Be_Normalized_To_UTC_View_Test() { - var personId = Guid.Parse("7a942bca-c911-4473-93aa-2daf88e18fb9"); - await _personRepository.InsertAsync(new Person(personId, "bob lee", 18) + var personName = "bob lee"; + await _personRepository.InsertAsync(new Person(Guid.NewGuid(), personName, 18) { Birthday = DateTime.Parse("2020-01-01 00:00:00"), LastActive = DateTime.Parse("2020-01-01 00:00:00"), }, true); - var person = await _personRepository.GetViewAsync(personId); + var person = await _personRepository.GetViewAsync(personName); person.ShouldNotBeNull(); person.CreationTime.Kind.ShouldBe(DateTimeKind.Utc);