functional-csharp-code icon indicating copy to clipboard operation
functional-csharp-code copied to clipboard

Can we create an Entity framework model using custom types?

Open MrYossu opened this issue 3 years ago • 8 comments

Take the Age type from chapter 3 as an example (source code).

Suppose I want to create a Person class, that EF will map to a table...

  public class Person
  {
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public Age Age { get; set; }
  }

I don't want Age to be mapped to a table, but can't see a way of convincing EF Core about this.

Anyone any ideas? Can we even use custom types with EF Core?

Thanks

MrYossu avatar Nov 21 '21 15:11 MrYossu

That's an interesting question, and hopefully someone who uses EF more than me will give a good answer... My feeling is that you may have to have 2 fields, the public Age Age field that is a computed property, and say private int AgeInternal that maps to the DB... In any case, EF is not FP-oriented in the least, so you're bound to have more issues of this kind if you want to combine EF and FP... but that doesn't mean that it can't work to some extent.

la-yumba avatar Nov 21 '21 19:11 la-yumba

@la-yumba Thanks for the reply. Not sure how a private property would work, as EF populates public properties.

However, your reply led me to a question I was about to ask...

Whenever I read material on FP, including your book, Scott Wlaschin's excellent "Domain Modeling Made Functional" (well worth reading, even for a C# programmer) and others, I always see data access code done with SQL. Maybe I'm spoilt, but I've been using Entity Framework for years, and the thought of losing the elegance and simplicity of Linq, and going back to writing SQL makes me shudder.

Do you really use SQL? Isn't there an FP way of using an OR/M?

Thanks again.

MrYossu avatar Nov 21 '21 20:11 MrYossu

EF has a NotMapped attribute that you could apply to the Age property.

josephshilo avatar Nov 22 '21 00:11 josephshilo

@josephshilo Thanks for the reply, but that only gets me part-way. I would still need to have a public property that EF could map to a database column, as well as a way of making that inaccessible for any other code, forcing them to use the Age property. Can't see how that could be done.

MrYossu avatar Nov 22 '21 14:11 MrYossu

@MrYossu does this help you: https://www.learnentityframeworkcore.com/configuration/fluent-api/ignore-method ?

if not, I'm sorry but I don't understand your scenario very well

WarBorg avatar Nov 30 '21 15:11 WarBorg

@WarBorg Thanks for the reply, but I'm not sure how that link helps.

The scenario is very simple. I want to have a custom type for (say) an Age property, so instead of using an int, I would use a custom Age class that includes a constructor that validates the age being passed in. However, I don't want Age to be mapped to a linked table, I want EF to map it to an int column in the table.

I want to know if this can be done with EF Core. @la-yumba suggested a private property and @josephshilo followed up by suggesting marking Age as NotMapped, but in both of these cases I am still left with the problem of having some property that EF can map to an int column on the table, without it requiring a separate table for Age.

Is that any clearer? Thanks again.

MrYossu avatar Nov 30 '21 15:11 MrYossu

@MrYossu ahh ok now I think I get it, you want to use the ValueObject pattern: please read here how this can be done in EF Core, hope this helps:

https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/implement-value-objects

WarBorg avatar Nov 30 '21 15:11 WarBorg

@WarBorg Thanks, that looks promising. I'm going to have to do a bit of reading!

MrYossu avatar Nov 30 '21 19:11 MrYossu