рдЯрд╛рдЗрдореНрд╕рдкреИрди рдХреЗ рд╕рд╛рде рдПрдХ рдореЙрдбрд▓ рдмрдирд╛рдПрдВ
class MyModel {
TimeSpan t;
}
---
MyModel m() {t = TimeSpan.MaxValue};
db_context.Add(m);
await db_context.SaveChangesAsync()
TimeSpan рдкреНрд░рдХрд╛рд░ рдПрдХ TIME рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХреЙрд▓рдо рдмрдирд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ TimeSpan рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЫреЛрдЯреА рдмрд╛рдзрд╛ рд╣реЛрддреА рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ TIME рдХреЗрд╡рд▓ '-838:59:59.000000' рд╕реЗ '838:59:59.000000' рддрдХ рдЬрд╛рддрд╛ рд╣реИ ред рдЬрдмрдХрд┐ TimeSpan 256204778:48:05.477580 рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддрд╛ рд╣реИред
Unhandled exception. Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
---> MySql.Data.MySqlClient.MySqlException (0x80004005): Incorrect TIME value: '256204778:48:05.477580'
---> MySql.Data.MySqlClient.MySqlException (0x80004005): Incorrect TIME value: '256204778:48:05.477580'
at MySqlConnector.Core.ServerSession.ReceiveReplyAsyncAwaited(ValueTask`1 task) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ServerSession.cs:line 774
at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ResultSet.cs:line 49
at MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 130
at MySql.Data.MySqlClient.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 391
at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList`1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\CommandExecutor.cs:line 62
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(DbContext _, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
рдорд╛рди рд░реВрдкрд╛рдВрддрд░рдг рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ TimeSpanToStringConverter
рдФрд░ TimeSpanToTicksConverter
рдпрджрд┐ рдЖрдкрдХреЛ рдПрдХ рдорд╣реАрдиреЗ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
@mguinness рдЯрд┐рдк рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдХреНрдпрд╛ рдореИрдВ рдЯрд╛рдЗрдордкреИрди рдХрдирд╡рд░реНрдЯрд░ рдХреЛ рдЯрд┐рдХреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рд╣реА рд╣реВрдВ, рдЬреЛ рдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рд▓рдВрдмрд╛ рд╣реИ?
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЕрдЧрд░ рдЖрдк рдХреБрдЫ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рдореИрдВ рдмрдЧ рд░рд┐рдкреЛрд░реНрдЯ рдмрдВрдж рдХрд░ рджреВрдВрдЧрд╛ред
TimeSpan рдкреНрд░рдХрд╛рд░ рдПрдХ TIME рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХреЙрд▓рдо рдмрдирд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ TimeSpan рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЫреЛрдЯреА рдмрд╛рдзрд╛ рд╣реЛрддреА рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ TIME рдХреЗрд╡рд▓ '-838:59:59.000000' рд╕реЗ '838:59:59.000000' рддрдХ рдЬрд╛рддрд╛ рд╣реИред рдЬрдмрдХрд┐ TimeSpan 256204778:48:05.477580 рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддрд╛ рд╣реИред
рдпрд╣ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╣рдо TimeSpan
рдХреЛ 24 рдШрдВрдЯреЗ рд╕реЗ рдЫреЛрдЯреЗ рдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрднрд╛рд▓рддреЗ рд╣реИрдВред рддреЛ new TimeSpan(1, 0, 0, 0)
рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдпрд╣ SQL рд╕рд░реНрд╡рд░ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреА рдирдХрд▓ рдХрд░рддрд╛ рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ @mguinness рдиреЗ рдмрддрд╛рдпрд╛, TimeSpanToTicksConverter
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдпрд╣рд╛рдВ рдЬрд╛рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рд╣реИред рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
```рд╕реА#
entity.Property(e => e.BestServedBefore)
.HasColumnType("bigint")
.HasConversion (рдирдпрд╛ TimeSpanToTicksConverter ());
It is equivalent to the following code:
```c#
entity.Property(e => e.BestServedBefore)
.HasColumnType("bigint")
.HasConversion(v => v.Ticks, v => new TimeSpan(v));
рдпрд╣рд╛рдБ рдПрдХ рдкреВрд░реА рддрд░рд╣ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:
```рд╕реА#
рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛;
System.Diagnostics рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛;
System.Linq рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛;
Microsoft.EntityFrameworkCore рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛;
Microsoft.EntityFrameworkCore.Storage.ValueConversion рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛;
Microsoft.Extensions.Logging рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛;
Pomelo.EntityFrameworkCore.MySql.Infrastructure рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛;
Pomelo.EntityFrameworkCore.MySql.Storage рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛;
рдиреЗрдорд╕реНрдкреЗрд╕ рдЗрд╢реНрдпреВрдХрдВрд╕реЛрд▓рдЯреЗрдореНрдкрд▓реЗрдЯ
{
рдкрдмреНрд▓рд┐рдХ рдХреНрд▓рд╛рд╕ рдЖрдЗрд╕рдХреНрд░реАрдо
{
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ int IceCreamId { рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ; рд╕реЗрдЯ; }
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдирд╛рдо {рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ; рд╕реЗрдЯ; }
рдкрдмреНрд▓рд┐рдХ рдЯрд╛рдЗрдорд╕реНрдкреЗрди рдмреЗрд╕реНрдЯрд╕рд░реНрд╡реЗрдб рдмрд┐рдлреЛрд░ {рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ; рд╕реЗрдЯ; }
}
public class Context : DbContext
{
public DbSet<IceCream> IceCreams { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseMySql(
"server=127.0.0.1;port=3306;user=root;password=;database=Issue1046",
b => b
.ServerVersion(new ServerVersion("8.0.20-mysql"))
.CharSetBehavior(CharSetBehavior.NeverAppend))
.UseLoggerFactory(
LoggerFactory.Create(
b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IceCream>(
entity =>
{
entity.Property(e => e.BestServedBefore)
.HasColumnType("bigint")
.HasConversion(new TimeSpanToTicksConverter());
entity.HasData(
new IceCream
{
IceCreamId = 1,
Name = "Vanilla",
BestServedBefore = new TimeSpan(0, 12, 0, 0)
},
new IceCream
{
IceCreamId = 2,
Name = "Chocolate",
BestServedBefore = new TimeSpan(0, 23, 59, 59)
},
new IceCream
{
IceCreamId = 3,
Name = "Artificial Vanilla",
// This will not work out-of-the box.
// Usage of a converter is necessary.
BestServedBefore = new TimeSpan(42, 11, 0, 0)
}
);
});
}
}
internal class Program
{
private static void Main()
{
using var context = new Context();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var iceCreams = context.IceCreams
.OrderBy(i => i.IceCreamId)
.ToList();
Debug.Assert(iceCreams.Count == 3);
Debug.Assert(iceCreams[0].BestServedBefore == new TimeSpan(0, 12, 0, 0));
Debug.Assert(iceCreams[1].BestServedBefore == new TimeSpan(0, 23, 59, 59));
Debug.Assert(iceCreams[2].BestServedBefore == new TimeSpan(42, 11, 0, 0));
}
}
}
```