Entity Framework Core set column to nvarchar(max) with code first - entity-framework

I am using Entity Framework Core 7.0.0 and in my OnModelCreating method I am trying to specify a column to be of type nvarchar(max).
In EF6 (not Core!), we were able to do something like:
modelBuilder.Entity<Log>().Property(p => p.Errors).IsMaxLength();
However, I am not able to figure this out in EF Core. Is there something similar available in EF Core that I am missing?
I know that it would normally default all properties of type string to nvarchar(max) but I am overriding DbContext's ConfigureConventions with the following, to default all string to 50 characters:
configurationBuilder.Properties<string>().HaveMaxLength(50);

With help of [Column] data annotation:
[Column(TypeName = "nvarchar(MAX)")]
With help of Fluent API:
entity.Property(p => p.Errors)
.HasColumnName("YourColumnName")
.HasColumnType("nvarchar(MAX)");
HasColumnName: the HasColumnName attribute is applied to a property to specify the database column that the property should map to when the entity's property name and the database column name differ.
HasColumnType: the HasColumnType method is applied to a property to specify the data type of the column that the property should map to when the type differs from convention.

Related

Entity framework 6 - Access the entity object during valueConverter

I have a project with Entity Framework Core 6 for SQL. it's a large project with a lot of entities and properties (and yes, a lot...). All properties are defined not nullable (bool, int etc.) because the SQL database tables all are not-nullable columns also. All good.
But now this project must works with an Oracle database server, and here are tables with nullable columns which not match with the not nullable entities (Oracle EF cannot match nullabe column with a not-nullable directly).
Changing all columns with not nullable with default value isn't possible. And making the entities nullable give us a lot of (test) work because it hits the logical part of code.
So, my challenge is to find a solution that nullable table columns can set not-nullable entity properties with a value or default and without changing the entity set of code.
Using the ValueConverter is the first solution but it isn't possible because a null value will never be passed to a value converter.
So I try it with a shadow property. I have this:
entityTypeBuilder.Ignore(property.Name);
entityTypeBuilder.Property<int?>($"_Nullable_{property.Name}")
.HasConversion<NullableIntConverter >()
.HasColumnName(oracleColumn.ColumName);
Here I ignore the original property for EF, then I add a shadow property with converter for the nullable type (<int?>). This is the valueConverter:
internal class NullableIntConverter : ValueConverter<int, int?>
{
public NullableIntConverter()
: base(
_convertToEntityProviderExpression,
_convertToDbProviderExpression)
{
}
private static readonly Expression<Func<int?, int>> _convertToDbProviderExpression = x =>
x.GetValueOrDefault();
private static readonly Expression<Func<int, int?>> _convertToEntityProviderExpression = x => x;
}
This works, a nullable column set the shadow property but not the original property.
The solution will be setting the original property during ValueConverter. But because of static it isn't really possible. Or maybe someone have a solution here? If I have the entity object, I can use reflection for setting the original property.
I hope that someone have a tip for a solution?

NPGSQL date time array

I'm attempting to use the timestamp[] field type in Postgres with NPGSQL, so that I can use the DateTime[] type in my Entity Framework models.
I've added this to my EF code first model.
[Column("HostUnavailableDates", TypeName = "timestamp[]")]
public DateTime[] HostUnavailableDates { get; set; }
I've created a migration and the database has updated successfully.
However I am getting this error when executing transactions with the model.
Message: System.InvalidOperationException : The property 'HostApplication.HostUnavailableDates' could not be mapped, because it is of type 'DateTime[]' which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
I've followed this answer which does not use any type of ignoring of the property. Is there something I need to do for the DateTime type in addition to what I'm currently doing?
Is DateTime in fact not supported at all in this case?
I'm using EF Core.
I'm assuming you're using Entity Framework 6.x. If that's the case, then arrays simply aren't supported, you'll have to switch to Entity Framework Core.

EF CORE How to Change NVACHAR to VARCHAR

In Entity Framework 6.X It was possible to change the default database type by doing this:
modelBuilder.Properties<string>().Configure(c => c.HasColumnType("varchar"));
In EF Core how can i do that?
The method Properties() doesn´t exists.
Since EF Core 6, based on github repository of entity framework (see here) :
previous versions of EF Core (before EF Core 6) require that the
mapping for every property of a given type is configured explicitly
when that mapping differs from the default. This includes "facets"
like the maximum length of strings and decimal precision, as well as
value conversion for the property type.
In the class that inherits from DbContext override ConfigureConventions
protected override void ConfigureConventions(
ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder
.Properties<string>()
.AreUnicode(false)
.HaveMaxLength(1024);
}
Thus all string properties can be configured to be ANSI (instead of Unicode) and have a maximum length of 1024, hence mapping string to nvarchar changes to varchar when migrations are applied to the database.

EF code first, model properties types to db data types

The EF will create Nvarchar data type from a property of type String.
Is there a list of how other types are treated by EF and what they will be represented as in the DB created from the model ? Thank you,
Check that mapping table: SQL-CLR Type Mapping. You can also change that default behavior using DbType attribute:
[Column(DbType="NVarChar(10) NOT NULL")]

Entity Framework 4.1 Code First: How is the Discriminator determined?

Currently I have class hierarchy defined with the Code First approach as follows.
E.F. has autogenerated a nvarchar(128) discriminator. It is not a key field.
How does Entity Framework determine what and what Type the discriminator field should be, and is it always the same, i.e. nvarchar? Is the discriminator at all accessible outside the database i.e. from LINQ to Entity?
Discriminator column is by default nvarchar because it stores names of your classes to differ between types - that is the whole point of this column: to allow EF knowing what class instance from your inheritance hierarchy it should create when it loads record from the database.
Discriminator column is not accessible by linq-to-entities. It is only used to map record to correct type.