AltairCA / EntityFrameworkCore.PostgreSQL.ColumnEncryption

NPGSQL Extension that supports native PostgreSql's [Raw Encryption Functions (encrypt_iv,decrypt_iv with aes-cbc/pad:pkcs)]
16 stars 3 forks source link

[Request] Support for MetadataTypeAttribute #6

Open onodera-sf opened 1 year ago

onodera-sf commented 1 year ago

We are using EntityFrameworkCore.PostgreSQL.ColumnEncryption. I have one request.

I think that "NpgsqlEncrypt" is supposed to be added to the property to be encrypted, When generating code with "Database first", "NpgsqlEncrypt" cannot be added because the code will be overwritten.

In ASP.NET Core, etc., there is a mechanism to artificially add attributes with "MetadataTypeAttribute" in consideration of this. I would appreciate it if you could adopt this for EntityFrameworkCore.PostgreSQL.ColumnEncryption as well.

[Code example]

Auto-generated code

namespace TestPostgres.Models.Database
{
  [Table("User")]
  public partial class User
  {
    [Key]
    public int ID { get; set; }

    [StringLength(32)]
    public string? Name { get; set; }
  }
}

Manual add code

namespace TestPostgres.Models.Database
{
  [MetadataTypeAttribute(typeof(UserMetadata))]
  public partial class User
  {
  }

  public class UserMetadata
  {
    [NpgsqlEncrypt]
    public string? Name { get; set; }
  }
}
AltairCA commented 1 year ago

Got this answer by using Chat GPT, can you give it a go?

In Entity Framework Core (EF Core), the Code-First approach is more commonly used for defining the model and the database schema based on the code. However, if you are working with an existing database (i.e., a Database-First approach) and you want to use custom attributes with metadata, you can still achieve this by leveraging EF Core's Fluent API.

Here's how you can use custom attributes with metadata in a Database-First scenario in EF Core:

  1. Create Your Metadata Classes: Define your metadata classes with custom attributes. These metadata classes represent the structure and validation rules of your database entities.
public class CustomerMetadata
{
    [Required]
    public string Name { get; set; }

    [MaxLength(100)]
    public string Email { get; set; }
}
  1. Map Your Metadata with Fluent API: In your DbContext class, use the Fluent API to map your metadata to the database entities. You can configure this during the OnModelCreating method override.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Customer>()
        .ForSqlServerHasAnnotation("MyCustomAttribute", "MyValue") // Example of a custom attribute
        .HasMetadata<CustomerMetadata>(metadata =>
        {
            metadata.Property(e => e.Name).HasColumnName("CustomerName");
            metadata.Property(e => e.Email).HasColumnName("EmailAddress");
        });
}

In the code above:

This approach allows you to maintain a separation of concerns by keeping your metadata in separate classes while using the Fluent API to map and configure your database entities when working with a Database-First approach in EF Core.

Please note that EF Core's primary approach is Code-First, where you define the model classes and let EF Core generate the database schema. The Database-First approach is less common but is still supported, and you can use the Fluent API to customize the mapping and metadata for entities in this scenario.