Hi, we store a .pfx certificate in a postgresql database, the problem is that everytime we generate a new migration, its detects an non existing change in the certificate, here is an example
```C#
public partial class SomeEntity
{
public virtual Guid Id { get; set; }
public virtual byte[] Certificate { get; set; }
}
In the Context, we have something like this
```C#
modelBuilder.Entity<SomeEntity>().HasData(new SomeEntity()
{
Id = Guid.Parse("57CCAF02-F4AA-AD43-A7AE-48DEC1C5FE01"),
Certificate = File.ReadAllBytes(Path.Combine(Directory.GetCurrentDirectory(), "Certificate.pfx"});
}
And then in the Migration Folder we have the "InitialCreate", and without any change in the context, we create a migration,using the command "Add-Migration test", we have as result something like this
```C#
public partial class test : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
schema: "postgres",
table: "some_entity",
keyColumn: "id",
keyValue: new Guid("57ccaf02-f4aa-ad43-a7ae-48dec1c5fe01"),
column: "certificate",
value: new byte[] { 48, 130, ... 8, 0 });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
schema: "postgres",
table: "some_entity",
keyColumn: "id",
keyValue: new Guid("57ccaf02-f4aa-ad43-a7ae-48dec1c5fe01"),
column: "certificate",
value: new byte[] { 48, 130, ... 8, 0 });
}
}
Another thing that we detected, (have in mind that this aplication runs in a linux container and we develop it in windows), when you wanna store a path in the database, if you put in the seed something like this
```C#
modelBuilder.Entity<PdfTemplate>().HasData(new PdfTemplate()
{
Id = Guid.Parse("FF57B2CD-2FA4-4048-9B48-B8B19B9A2E55"),
Name = "Template1",
PathToView = Path.Combine("Views", "PDFs", "Template1.cshtml")
});
And when we generate a migration, it does something like this
```C#
migrationBuilder.InsertData(
schema: "postgres",
table: "pdf_template",
columns: new[] { "id", "name", "path_to_view" },
values: new object[] { new Guid("ff57b2cd-2fa4-4048-9b48-b8b19b9a2e55"), "Template1", "Views\PDFs\Template1.cshtml" });
As you can see, when the migration is generated its resolve the PATH.Combine method, the result is ok in windows, but when it runs on the linux container, the path doesnt work anymore. As a workaround, we replace the string generated by path.combine resulting in something like th
```C#
migrationBuilder.InsertData(
schema: "postgres",
table: "pdf_template",
columns: new[] { "id", "name", "path_to_view" },
values: new object[] { new Guid("ff57b2cd-2fa4-4048-9b48-b8b19b9a2e55"), "Template1", Path.Combine("Views", "PDFs", "Template1.cshtml") });
And we get it to work in both SO, for this last thing, there is a way for doing this "workaround" automatically?
EF Core version: 2.1.1
Database Provider: Npgsql.EntityFrameworkCore.PostgreSQL (2.1.1.1)
Operating system: Win 10 Pro 1803
IDE: Visual Studio 2017 15.8.1
@ajcvickers IIRC the decision was to have reference comparison for byte arrays since they are typically big blobs and we don't want to pay the price of a value comparison each time we save an entity. This seems to be backfiring here as the instances are different and seeding detects a "change".
How about modifying the comparison behavior to first compare references, and only if unequal we do a value comparison? This would keep the typical scenario (unchanged byte array when saving) very fast, but will fix this issue.
@roji That's something we should consider. Related to this, while working on the spatial stuff, @bricelam has uncovered several areas for improvement in around these things--for example, see #13098. I've got an item in my list of things to do to look at this from a wider perspective and see what we can do for 2.2 and 3.0.
Hi, i just found that with DateTime.MaxValue it has the same behaviour than the one with byte[], i have this seed
modelBuilder.Entity<Entities.Tasks>().HasData(new Entities.Tasks()
{
Id = Guid.Parse("50475284-2956-4F4B-9C51-B6D87C112D32"),
Status = DTO.Enum.TasksStatus.Waiting,
CreationDate = DateTime.MinValue,
StartDate = DateTime.MinValue.Date.AddDays(1).AddHours(8).AddMinutes(30),
LastRunning = DateTime.MinValue,
EndDate = DateTime.MaxValue,
Period = TimeSpan.FromHours(24),
Json = JsonConvert.SerializeObject(string.Empty)
});
And then, when we create a migration without any change in the context, we get this
public partial class InitialCreate3 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
schema: "payment",
table: "tasks",
keyColumn: "id",
keyValue: new Guid("50475284-2956-4f4b-9c51-b6d87c112d32"),
column: "end_date",
value: new DateTime(9999, 12, 31, 23, 59, 59, 999, DateTimeKind.Unspecified));
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
schema: "payment",
table: "tasks",
keyColumn: "id",
keyValue: new Guid("50475284-2956-4f4b-9c51-b6d87c112d32"),
column: "end_date",
value: new DateTime(9999, 12, 31, 23, 59, 59, 999, DateTimeKind.Unspecified));
}
}
BUT it does not behave like this, if you use DateTime.MinValue.
EF Core version: 2.1.1
Database Provider: Npgsql.EntityFrameworkCore.PostgreSQL (2.1.1.1)
Operating system: Win 10 Pro 1803
IDE: Visual Studio 2017 15.8.2
@fpanaccia I think there is likely a different root cause here, so I moved this to #13208