-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using ValueOf with Entity Framework Core? #28
Comments
I'm not that experienced with EF, but maybe this will work?
Failing something like that, you're probably better off using something like AutoMapper to separate your entities (classes that map 1:1 to fields in your database and are only used in code that directly interacts with the DB) and your models (classes that use ValueOf). |
Vogen is similar to this but it has certain opinions/constraints on safety (for instance, not being able to create default instances of value objects). It's also focused on speed; there's almost no overheard compared to using a primitive directly. |
@chucker tried your suggestion just now, same error as before. In fact even when I annotate the property with |
@SteveDunn thanks for the tip, for the time being I've switched back to working in primitive obsession mode just because I want to make progress on the actual code I gotta get done (it's for work unfortunately). But I'll keep your package in mind for when I do the refactoring down the line, hopefully sooner rather than later. |
I haven't really used EF for a while, but I suspect you need a custom ValueConverter https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions?tabs=data-annotations Another option might be https://docs.microsoft.com/en-us/ef/core/modeling/backing-field?tabs=data-annotations |
Using value conversions with ValueOf works perfectly fine. public class CustomerContext : DbContext
{
public CustomerContext(DbContextOptions options) : base(options)
{
}
public DbSet<Customer> Customers => Set<Customer>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Customer>()
.Property(e => e.Id)
.HasConversion(
convertToProviderExpression: id => id.Value,
convertFromProviderExpression: id => CustomerId.From(id));
modelBuilder
.Entity<Customer>()
.Property(e => e.Email)
.HasConversion(
convertToProviderExpression: emailAddress => emailAddress.Value,
convertFromProviderExpression: emailAddress => EmailAddress.From(emailAddress));
}
} Check out my repository for a fully working example: |
If you want a generic ValueOfConverter:
|
I am reopening the issue. I tried, but I'm not able to map tuple value to EfCore. Like:
And I want it to be OwnedBy entity or set as ComplexProperty. But everything I tried doesn't work. So, is ValueOf rather for single primitives than whole structs? |
Hi, I'm trying to incorporate your excellent library into my EFCore model classes, for example:
Where
LongId
,NameLabel
,GuidStr
have C# primitive types oflong
,string
,string
respectively, with appropriate validation checks (e.g. under a certain length forNameLabel
, and of certain format forGuidStr
).The code compiles fine, however when I actually try to fetch one of the above record from the database, I'm running into this error:
System.InvalidOperationException: The property 'Account.Id' is of type 'LongId' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
I also tried to annotate the model with something like
[Column(TypeName = "bigint")]
on theId
property for example, and it didn't do anything. So I just wanted to ask you if what I'm trying to do is reasonable and/or feasible. Maybe I should just return to using primitive C# types?The text was updated successfully, but these errors were encountered: