Comments (18)
@myrup I'm actively working on this, it involves many things across the stack. I'm really hoping it'll make it into preview2.
from efcore.pg.
This has been merged and will be released with 2.1.0-preview2.
For now, the depends on Npgsql 4.0.0, which is still in development - not ideal. We'll see how the release cycles of EF Core and Npgsql coincide and see what to do.
from efcore.pg.
@ajcvickers, @divega and everyone else interested in this, I've completed a hacky prototype that successfully maps to PostgreSQL native enums. Enum types can even be defined using a fluent API on the model and are created as part of migrations. I will probably complete support for this, including scaffolding, for 2.1.
It's really, really nice to be able to do all this with EF Core, great going guys!
from efcore.pg.
@julielerman you're not going to be able to map to a PG enum because of limitations in EFCore, this is what this issue is about. My hope is that when EFCore does support native database enums you'll be able to have the same model mapping to enum on PostgreSQL and to int on sqlite.
from efcore.pg.
@roji Any news on when this feature will be implemented or how this issue can be bypassed?
from efcore.pg.
@roji Very cool! I have a PR out for the enum literal bug.
from efcore.pg.
@roji Thanks for the update. That sounds really cool! It is also great because you are helping us validate (and improve 😄) the type mapping design.
from efcore.pg.
It seems the EF7 doesn't support database enum mapping right now, mapping enums to numeric types instead. Have opened dotnet/efcore#3620 for this.
from efcore.pg.
Hi is there a workaround until this get fixed?
from efcore.pg.
I think you should be able to have enums on your entities, it's just that they'll be mapped to database int columns instead of PostgreSQL enums. I haven't confirmed this yet, though.
from efcore.pg.
Yes, I'm using enums and getting integers by default. I haven't tried mapping to a posgres enum type but I do need to flip to sqlite occasionally so leaving it as int.
from efcore.pg.
thanks. I realize now that enum isn't just a type to specify with HasColumnType so understand why even though basic enum support is now working in EFCore, that this is a much farther stretch.
from efcore.pg.
@roji I can confirm that using a enum in C# and mapping it to an int in the database does work.
My problem is that we do already use enums as custom types in postgres. So I was looking for a solution for that case. Anyway I've a working solution it's not the best but it works. It does require that the enum in C# has the PgName attributes set.
Change the model like this:
[NotMapped]
public MyEnum Type
{
get
{
return GetEnumValueByPgName(MyEnum.Value1, this.TypeDatabase);
}
set
{
this.TypeDatabase = value.GetPgName();
}
}
[Column("type")]
public string TypeDatabase { get; protected set; }
This is the helper function I use:
/// <summary>
/// Gets PgName value for enum
/// </summary>
/// <param name="enumVal">The enum value</param>
/// <returns>PgName or empty if not found</returns>
public static string GetPgName(this Enum enumVal)
{
var type = enumVal.GetType();
var memInfo = type.GetMember(enumVal.ToString());
if (memInfo.Count() == 0)
{
return null;
}
var attributes = memInfo[0].GetCustomAttributes(typeof(NpgsqlTypes.PgNameAttribute), false).ToArray();
if (attributes?.Length > 0)
{
var name = (NpgsqlTypes.PgNameAttribute)attributes[0];
if (name != null)
{
return name.PgName;
}
}
return string.Empty;
}
/// <summary>
/// Get enum value by PgName. Use as workaround for bug in EfCore.
/// </summary>
/// <param name="defaultValue">Default value to set if could not find a match</param>
/// <param name="pgname">PgName used in database</param>
/// <returns>Mapped value or default value</returns>
public static TEnum GetEnumValueByPgName<TEnum>(this TEnum defaultValue, string pgname)
{
if (string.IsNullOrEmpty(pgname))
{
return defaultValue;
}
var type = typeof(TEnum).GetTypeInfo();
if (!type.IsEnum)
{
throw new TypeLoadException("Given type is not an enum.");
}
foreach (var item in type.GetMembers())
{
var attributes = item.GetCustomAttributes(typeof(NpgsqlTypes.PgNameAttribute), false).ToArray();
if (attributes?.Length > 0)
{
var name = (NpgsqlTypes.PgNameAttribute)attributes[0];
if (name != null && name.PgName == pgname)
{
return (TEnum)Enum.Parse(typeof(TEnum), item.Name);
}
}
}
return defaultValue;
}
from efcore.pg.
@vankooch I'm surprised this actually works, but if it does why not.
from efcore.pg.
@vankooch Hey, your solution only works for retrieving right? I tried to use but I still get the Npgsql.PostgresException: 42804: column "payment_type" is of type payment_type but expression is of type text
by at insertion time.
from efcore.pg.
@CoffeeDreamLabs there is a slight chance that this will be possible in the upcoming 2.1 release, but it doesn't depend on me or on Npgsql, but rather on EF Core itself. Go to dotnet/efcore#3620 and express your interest there.
from efcore.pg.
@ajcvickers will wait for that to be fixed (dotnet/efcore#11041), there's more than enough to do in the meantime...
from efcore.pg.
@roji dotnet/efcore#11041 was merged. Is there any way to start using your fix today?
from efcore.pg.
Related Issues (20)
- Issues with configuring tsvector columns for migrations HOT 7
- !string.IsNullOrEmpty producing incorrect sql HOT 1
- Question about EnableRetryOnFailure HOT 5
- Fix null semantics for row value comparison
- The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded HOT 8
- ExecuteSqlRawAsync with NpgsqlParameter and IEnumerable value HOT 3
- ExecuteUpdate/Delete produce invalid SQL when table is present both as the primary and in a join HOT 10
- UseCollation don't use collation HOT 1
- Precompiled query/NativeAOT work HOT 1
- gin_trgm_ops fails if used for multiple columns
- Database connection interceptor is not being called HOT 2
- Translate Contains to LIKE or ILIKE based on StringComparison argument. HOT 3
- FromSqlRaw parameterized query produces an error but same query without parameters works
- Should optimistic concurrency work when manually setting the version? HOT 1
- Add new overload for `EnableRetryOnFailure` that allows to pass in `maxRetryCount` and `maxRetryDelay`.
- Stop PG from using a generic plan when an array is parameterized
- How to properly set up IsRowVersion and should it be included in the migrations HOT 3
- Translate consecutive array of integers to "between x and y" HOT 1
- Issue with Mapping and Querying xmin as RowVersion in PostgreSQL Using EF Core HOT 3
- Latest preview version for .NET 9 does not support RC1 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from efcore.pg.