Here Is the Most Powerful EF Core Configuration Technique

  Рет қаралды 13,111

Zoran Horvat

Zoran Horvat

Күн бұрын

Пікірлер: 135
@martinoserri8814
@martinoserri8814 Ай бұрын
The video I've been waiting for!
@elraito
@elraito Ай бұрын
Im amazed. I dont know exactly what detail but somehow this video seemed like a massive upgrade in production quality. Careful now. We might start to expect this from you from now on.
@zoran-horvat
@zoran-horvat Ай бұрын
@@elraito There are about five rules to configuring EF Core and those give you the power to map object models of immense complexity into an elegant and fast relational schema. The trouble is that even experienced developers stay at using about two out of five rules, and then struggle with issues of all kinds. Even to the point of blaming the Entity Framework for their failure, and avoiding to use it.
@jordanfarr3157
@jordanfarr3157 Ай бұрын
🤯🤯🤯🤯🤯 okay you win. I'll join the Patreon.
@amakazor8632
@amakazor8632 Ай бұрын
Hello Zoran! I have started watching your videos recently trying to expand my C# knowledge and they are an absolute goldmine. Thank you very much for producing content of this quality, showcasing this high of a skill level while still being easy to follow and learn from!
@Tesfamichael.G
@Tesfamichael.G Ай бұрын
Your lessons are all wonderful to me! You seem to be the Nicola Tesla of C#. живјели!
@AK-vx4dy
@AK-vx4dy Ай бұрын
Glad you take this topic on the table, i also asked many times. I personaly had to use .HasConversion but from diffrent reason, i have a problem with consistent interpretation of datetime type, because sql type has no timezone info or even source info like DateTime in C# has, so i added conversion wich stored datetime as UTC always in database and EF done whole job. Value conversion are nice, but sometimes they make reporting from external tools harder (because there is no dictionary or mapping in database).
@Gonzo345
@Gonzo345 Ай бұрын
I simply love I’m not alone loving EF Core. Thanks for this video and congratulations!
@handlez411
@handlez411 Ай бұрын
This is awesome. You split my head open far too often!
@zoran-horvat
@zoran-horvat Ай бұрын
@@handlez411 Sorry, I find a lot of joy in doing that.
@handlez411
@handlez411 Ай бұрын
@@zoran-horvat Love it
@peterriesz69
@peterriesz69 Сағат бұрын
Great Video! It inspired me to try adding a MailAddress ValueConversion to a project I'm currently working on but I had to bail once as I realised I would no longer be able to query email addresses by host. Using the CultureInfo example, lets say we have book cultures fr, en-GB, en-US. Now we just want to retrieve all english (en) books. Previously this could have been achieved with books.Where(book => book.Culture.StartsWith("en")). I am pretty sure books.Where(book => book.Culture.TwoLetterISOLanguageName == "en") is going to throw. Using custom value conversion will limit your ability to query these fields with EF.
@cmdr_thrudd
@cmdr_thrudd Ай бұрын
Another great video and also some good laughs. I never knew we could do value conversions, I'm going to have to try this in my next project. Thank you :)
@adiazwise
@adiazwise Ай бұрын
Excellent approach, I will try to implement it in my projects.
@shmupful
@shmupful Ай бұрын
Great content, loved the convertion of PublicationDate to int
@vovcheable
@vovcheable 19 күн бұрын
i love your sense of humor
@ElOroDelTigre
@ElOroDelTigre Ай бұрын
Amazing as usual. This is top tier content.
@AndersBaumann
@AndersBaumann Ай бұрын
Indeed a good technique. Well done, Zoran!
@zoran-horvat
@zoran-horvat Ай бұрын
@@AndersBaumann You ended up in it.
@JonasMotiejauskas
@JonasMotiejauskas Ай бұрын
Great video! It would also be very interesting to hear more about owned types and discriminations to have even more decoupled models and entities. Also how to best map immutable types / lists to support functional design
@Buutyful
@Buutyful 22 күн бұрын
hey zoran! thx for the video as always :) in any of your entities i see fk, why is that? do u use shadow props?
@conbag5736
@conbag5736 Ай бұрын
Excellent video as always Zoran. Yet, I do find parts of this implementatiom a little bit lacking in your usual elegance. I don't mean that as a critcism in any way - I certainly could not do it better - but there's a few observations which I think are worth making. Firstly, the pairing of EditionToString and StringToEdition struck me as potentially problematic. As it stands, when there are only two implementations of IEdition, it is fine. However, if there were more implementations, and you had to account for every one inside both switch statements - where each is exactly the inverse of the other - this seems like a recipe for bugs - where one type is inadvertently serialized/de-serialized as another. Secondly, the private property "PublicationKind". In the Configuration class, you are concerning yourself with setting the value of a private field. Under normal circumstances, you wouldn't ever do this - but you need to do it here - and worse, you use a magic stiring representing the property name to do so. This feels like we're breaking one of the cardinal rules of OOP here. The conversion of PublicationDate to/from an int is also a bit confusing. If the opposite of this rich-domain model is using simple primitive types - persistance is easy. DateTime in C# world maps to DateTime/DateTime2 in SQL world. Whereas here, we have to come up with an elaborate multiplication/division system just to ensure we get the correct type. Again, another superb video, but I think the commenters at the beginning of the video have a valid point. Persisting this is tricky.
@zoran-horvat
@zoran-horvat Ай бұрын
@@conbag5736 You are right about the edition persistence. I used formatting here to demonstrate the technique, but in reality I would split it into two columns - one for the enum and one for the accompanying number. Setting up the PropertyKind with a "magic string" is the only possibility,. EF is using reflection to access private fields and properties, but that means lambdas and nameof are inaccessible. It is common to use strings to specify properties in EF Core configurations. Regarding the dates to int conversions, it is not possible to avoid it. The domain model proposes incomplete dates, which cannot be persisted as any date type. That would require all three components of the date, but one or two might not be available.
@haraheiquedossantos4283
@haraheiquedossantos4283 Ай бұрын
I think it all depends which side you wanna be. The pure and "clean" domain models with "no" knowledge how it persists so far, but you have those complexities of transform to data/persistent models and converters. Or you could simply use data models (anemic domain models) in CRUD nature style without complexities. Which one to choose? It depends of which type of domain problems you are solving and complexity of the behaviors of your system. Great videos btw. Congrats 🙏
@zoran-horvat
@zoran-horvat Ай бұрын
@@haraheiquedossantos4283 Anemic models work fine on very small services with mostly CRUD-type requirements. As soon as domain rules start to appear, a proper domain model becomes a necessity.
@Folsets
@Folsets Ай бұрын
Thanks for the video!
@pl4gueis
@pl4gueis Ай бұрын
Absolutely loved the video. My key take away is that proper design upfront makes for a pleasant development experience later. I lazily relied on C# Tooling to create migrations and stuff for me which works nice but makes integrating proper Design more complicated because you need DTOs. This approach forces to actually learn EF Core deeply and use it properly. Thanks for sharing. Its time to study EF Core in more detail. Quick question. How did you do that SQL Query in VSCode?
@zoran-horvat
@zoran-horvat Ай бұрын
EF Core is a powerful library. It also allows for a simple decoupling via interfaces, such as a custom IRepository. That extension I use in VS Code is SQL Server extension by Microsoft. It is very useful.
@Jojor11
@Jojor11 Ай бұрын
Ok i have to look more carefully into this topic. It feels like the last piece I need to really go into a more organized approach and build the code in terms of what the application does instead of everything going around how the data will be stored in DB, which has been a problem multiple times as the app evolves. Very interesting
@ScrotoTBaggins
@ScrotoTBaggins Ай бұрын
Brilliant!!!
@cesarpinto3276
@cesarpinto3276 Ай бұрын
Beautiful video. What's your opinion on this take with a functional design? Do you just drop EF Core for a document database?
@zoran-horvat
@zoran-horvat Ай бұрын
EF Core is designed to track entities, which makes it inappropriate for immutable models. That is a pity, because it has a powerful implementation of IQueryable.
@cesarpinto3276
@cesarpinto3276 Ай бұрын
@@zoran-horvat That makes sense, and it is unfortunate. Will you be doing a video on persistence in a functional immutable design? I've seen all of your functional videos and courses and always have wondered how you would approach it
@zoran-horvat
@zoran-horvat Ай бұрын
@@cesarpinto3276 I plan to do something of that sort, but it is not a priority now. Simply, Dapper does that out of the box, mutable or immutable. However, I have a more realistic plan of showing a combination of mutable entities with immutable contained objects. That is a more interesting proposition in my view, and it is supported by EF Core via complex types and value conversions.
@nanny07
@nanny07 Ай бұрын
Hi Zoran, thanks for the video! How about mongo? Should we use IBsonSerializer to achive the same results?
@zoran-horvat
@zoran-horvat Ай бұрын
@@nanny07 You can always choose a document database if the problem you are solving is of the document type.
@viride
@viride Ай бұрын
Hi Zoran, great video! If I understand correctly, using this approach would make Dapper or database browsing using sql unusable (if I am wrong please correct me). Do you think that this approach would be worth it in production situations?
@zoran-horvat
@zoran-horvat Ай бұрын
@@viride I am using this in production code regularly. Regarding Dapper, it remains what it is. If you want to be the master of SQL and the schema, then Dapper is the way to go. If you wish to have more time with C# objects, then EF Core 8 is a powerful library that will help you develop the domain model.
@okcharles7
@okcharles7 Ай бұрын
Even when using Dapper, you can still use EF Core in design time, which means that the converting from runtime objects to table ones in this video, the first parameter in HasConversion(objectToRecordExpression, recordToObjectExpression), can be utilized when you update DB. After the time, you can use Dapper to query. However, mapping remains as your job, which just means your mapping code will be used instead of the second parameter of the HasConversion method. I think designing with EF Core design tools is recommendable even if you are a master of Db and query, especially in the case you are responsible for both code and DB. It can eliminate a lot of human errors in dealing with strings for queries throughout the application life cycle and, in result, you can save a lot of time.
@dobripopov8466
@dobripopov8466 Ай бұрын
Excellent approach! I am tired of looking at Clean architecture tutorials which advise you to abstract EF by creating custom IRepository and IUnitOfWork. EF Core has such a wonderful feature to map domain models to db. Why nobody uses it?
@pl4gueis
@pl4gueis Ай бұрын
Most likely because Tutorials don't cover it and people don't read documentation :D
@zoran-horvat
@zoran-horvat Ай бұрын
There is a lot of dogma around the design. I don't like that at all. For example, many programmers dismiss the use of ORMs on the grounds that they cannot decouple the domain model from infrastructure. But they fail to see they don't need that decoupling. They will never benefit from such absolute decoupling, but they will rob their application from a myriad of useful optimizations.
@Adam-vg5yz
@Adam-vg5yz Ай бұрын
@@zoran-horvat Very interesting to see you say this! I have been struggling with this back and forth for weeks now. Prior to watching this video, I was convinced the best solution would be to have my domain objects injected with an IRepository interface, with the implementation in my infrastructure project. Then, I could have those Repositories handle the mapping between my domain models and my persistence models. I used to assume that Clean Architecture examples simply omitted the strict seperation between domain/persistence for brevity. Maybe I need to spend more time learning about EF Core and how much smarter it is than me!! This video has given me a lot to think about, and has gotten me very excited. Thank you Zoran :)
@zoran-horvat
@zoran-horvat Ай бұрын
@@Adam-vg5yz EF Core 8 has plugged an ancient hole in its own design with complex types. Now its mapping capabilities are so powerful that you can offload the entire mapping back and forth to it and only work with the domain objects.
@Rademcz
@Rademcz 27 күн бұрын
Would be also great to see how to query this. For example, what If I need to efficiently retrieve only books that are planned to be published this year? How do I get to execute the condition in db engine instead of fetching the whole tables?
@zoran-horvat
@zoran-horvat 27 күн бұрын
@@Rademcz I have a few videos in the queue that will cover querying by complex objects.
@icarohenrick
@icarohenrick Ай бұрын
Thank you Thank you Thank you!!!!
@allinvanguard
@allinvanguard Ай бұрын
Cool stuff! I'm curious, would this also have ended up with a resonably decent result when using the built in EF Core TPH / TPC mapping? Especially TPH sounds quite similar to your approach, but in this case you took over the steering wheel. Would EF have handled this similarly?
@zoran-horvat
@zoran-horvat Ай бұрын
@@allinvanguard You are right, I have applied TPH in combination with something that looks like EF Complex Type mapping. I plan more videos about dealing with record types in EF Core, which will shed even more light on that
@HenrryPires
@HenrryPires 11 күн бұрын
good video
@Robert-yw5ms
@Robert-yw5ms Ай бұрын
I have a question. How smoothly does this work with LINQ? For instance, if I do var americanBooks = await context.Books.Where(b => b.CultureInfo.Name == "en-US").ToArrayAsync() will EfCore be smart enough to translate my predicate into SQL, or will it pull everything into memory in order to filter?
@zoran-horvat
@zoran-horvat Ай бұрын
@@Robert-yw5ms Actually, you would use the CultureInfo in the LINQ query, and EF Corey would apply the same value transform to construct the SQL query for you. It works out of the box.
@Robert-yw5ms
@Robert-yw5ms Ай бұрын
@@zoran-horvat Ah so I would do .Where(b => b.CultureInfo == new CultureInfo("en-US")) That's pretty neat.
@zoran-horvat
@zoran-horvat Ай бұрын
@@Robert-yw5ms Yes. That is an extremely useful feature in EF Core. Between the lines, which may not be obvious at first, the type you use must have a proper implementation of Equals which behaves the same as equality comparison of primitive values in the database. Otherwise, you might get rows back which you did not expect. In your example, SQL would compare a string "en-US" to what it finds in the database. Depending on the settings, that would even equal "en-us", small letters, in the database, but that is fine with us. The trouble would be if CiltureInfo.GetCultureInfo("en-us") is not equal to CultureInfo.GetCultureInfo("en-US"), which I think is not the case. You can imagine this duality of comparisons leading to troubles in certain cases.
Ай бұрын
Thank you for good stuff. One bite though 😂. At 9:44 I see the stuff I require from collegues during code reviews: when throwing try to give as many hints as possible. In this case arg exc telling what exactly edition type wasn't supported. And just few moment later, when converting string to edition, it's just "Unsupported edition format" 😢
@zoran-horvat
@zoran-horvat Ай бұрын
Actually, I do not advise showing string data in the log. You cannot tell if those data are subject to privacy concerns.
@dusanknezevic9072
@dusanknezevic9072 Ай бұрын
Great content! I did something similar in a project a few years ago in EF Core 6. Value conversions are just great. And I almost got laid off project because lead architect was furious I didn't use Unit Of Work and Repository interfaces wrapping DbContext and "hiding" EF Core 🤣like a plague. The last strawman argument of that architect for using Repository and UoW interfaces was that errors can happen when parsing unsupported data (they can always happen when using external data). EF Core 8 went above and beyond by adding ComplexType mappings and more cases of mappings, type conversions and other goodies. Your conversions of `Type` properties seem very similar to what EF Core does with TPH and TPC apporaches when mapping class hierarchies.
@zoran-horvat
@zoran-horvat Ай бұрын
@@dusanknezevic9072 Yes, my conversion of Type is the exact copy of what EF does in the similar situation.
@KubaSzostak
@KubaSzostak Ай бұрын
Thanks!
@zoran-horvat
@zoran-horvat Ай бұрын
Thank you!
@petervo224
@petervo224 Ай бұрын
Sorry if I miss it in the video: Why prefer mapping to PublicationDate as int instead of date column?
@zoran-horvat
@zoran-horvat Ай бұрын
Because day or day and month parts might be missing. That was the customer's requirement. You cannot write a date value with its day being zero or the month being zero.
@petervo224
@petervo224 Ай бұрын
Ah! Sound like replacing the missing parts with 01s or end day/month can be misleading and not acceptable by the requirements... Got it!
@zoran-horvat
@zoran-horvat Ай бұрын
@@petervo224 Yes, any of the substitutes could be the valid intended value, and then the information is lost.
@lukaszmatecki4218
@lukaszmatecki4218 14 күн бұрын
Why not Json for complex types?
@zoran-horvat
@zoran-horvat 14 күн бұрын
@@lukaszmatecki4218 Why move away from relational types in a relational schema? The queries are yet to come. Would you rather mix JSON and relationships in the same query?
@hosseinsanjabian164
@hosseinsanjabian164 Ай бұрын
Well Done, i love you're Videos but this approach ( using too many complex object ) doesn't introduce overhead? like in scenario when we want get List (With Pagination) for each item in that list ef need to convert them to real object use you're conversion rules.
@zoran-horvat
@zoran-horvat Ай бұрын
@@hosseinsanjabian164 You would only use full domain objects in commands. In queries, you can strip the query down to only load the fields you will actually use in the result.
@goliafffff
@goliafffff Ай бұрын
Now I have another question. How to deserialize this model from request?
@zoran-horvat
@zoran-horvat Ай бұрын
@@goliafffff You mean load from the database? If that is the question, then mappings and conversions work both ways. You just get the objects back.
@goliafffff
@goliafffff Ай бұрын
@@zoran-horvat No. I mean we have rest API request to our app. And we should deserialuze incoming json to our oop model.
@zoran-horvat
@zoran-horvat Ай бұрын
@@goliafffff The OOP model you are referring to has constructors and factory methods. I don't see the problem in creating any of those objects.
@goliafffff
@goliafffff Ай бұрын
@@zoran-horvat How JSON serializer will decide which type of Edition to choose?
@zoran-horvat
@zoran-horvat Ай бұрын
@@goliafffff You choose based on JSON content. Don't fall into the trap of believing there is one JSON format for one set of types in the project. That may only be true in the simplest projects, which I do not cover in my videos.
@KubaSzostak
@KubaSzostak Ай бұрын
@AK-vx4dy
@AK-vx4dy Ай бұрын
About IEdition... why do not add ToString, FromString or smillar methods to do interface and concrete types will be responsible to implement such operations ? Also i have dillema what to do if we get some garbage or unsuported format from DB, exception may catch users in very strange places and/or inside some multistep operation with hard to understand error.Defaulting to some safe value is also not ideal... I don't know it is good solution here, but.... Aproach of converting at EF level has one big advantage - consistency in behaviour without risking that next "genius" will bring own ideas ;)
@zoran-horvat
@zoran-horvat Ай бұрын
@@AK-vx4dy Adding conversion to the interface would burden its implementers with guaranteeing uniqueness and parsability, schema evolution, backward compatibility, and a few other things they should never be responsible for. There is also the question of who would parse the strings.
@AK-vx4dy
@AK-vx4dy Ай бұрын
@@zoran-horvat Wise points. I would not trust them ;) However how to do not allow them to add new incarnations of such interace without other party expaning conversion methods (Uncle Bob mubling OCP in the corner ;)? As i understand it will throw at runtime in this implementation ?
@terjeengelbertsen9215
@terjeengelbertsen9215 Ай бұрын
Any source code available?
@zoran-horvat
@zoran-horvat Ай бұрын
@@terjeengelbertsen9215 Yes, on Patreon. There is the link in the description.
@adambickford8720
@adambickford8720 Ай бұрын
This feels bad to me. If you're going to violate normal forms with things like `edition`, why create a limited de/serialization format instead of just throwing it in json? At least as json things like schema migration are well understood and you could still query it in postgres.
@zoran-horvat
@zoran-horvat Ай бұрын
@@adambickford8720 How did I violate normal forms?
@adambickford8720
@adambickford8720 Ай бұрын
@@zoran-horvat In the case of `SeasonalEdition` you are storing 2 values in 1 column which is why you have to split it. Why not just use json and you don't have to worry about all kinds of de/serialization issues?
@zoran-horvat
@zoran-horvat Ай бұрын
@@adambickford8720 JSON is hard to query in a SQL database. It is also an overkill compared to a primitive column type in a table where all other columns already have simple types.
@adambickford8720
@adambickford8720 Ай бұрын
@@zoran-horvat agreed, which is why breaking normal forms feels bad. but if we must, json has first class support in postgres :) I disagree its overkill. This approach causes you to write custom de/serializers for every new type. That's begging for injection attacks. And if you have nested objects, good luck!
@marvinxulu7816
@marvinxulu7816 Ай бұрын
You thinking defets most people it's like you what people do 😂 you make me feel dumb but i still watch😢
@n00bje
@n00bje Ай бұрын
Interesting concepts. I get why you use them, but I feel like this is becoming an over engineered project that is very restrictive, difficult to hand over to inexperienced people, or people with a limited knowledge of the domain/framework. Adding a new class that implements IEdtion is easy, but it's not obvious for new people that there are also two conversion functions you have to change, and probably some work/mapping in your API and front-end. I would be very tempted to replace IEdition and its implementations with just a string, or a FK to a (power)user-editable lookup table. Having to contact the developer and wait for a new release just so you can enter a new edition like "anniversary", "special" or "limited" also seems so unnecessary. Especially when you have to go through a vendor, get a quote, have it approved, etc. I'd probably replace PublicationKind with a FK to another user-editable table as well, because I just *know* that Published, Planned and NotPlannedYet is not going to be enough eventually.
@zoran-horvat
@zoran-horvat Ай бұрын
@@n00bje I think your fear of other people's ignorance is exaggerated. People know a lot. On the other hand, I find a great error in your idea of stringifying the domain model out of fear for how it would be persisted. The entire persistence configuration for that polymorphic type is located in just one place, as it should be. Changing the domain model is expected, and welcome, and it must be accompanied with the corresponding modifications at the edges of the system (persistence, serialization, DTOs, service contracts, etc.). We just don't give up programming principles because there exists a database. The idea of turning the PublicationKind into an entity has no justification from the point of view of the relational schema modeling.
@ldeerosel
@ldeerosel Ай бұрын
What about validation? In your logic a phone number can be "hello there!"
@n00bje
@n00bje Ай бұрын
@@ldeerosel I create my own attributes that inherit from System.ComponentModel.DataAnnotations.ValidationAttribute, or inherit from IValidatableObject, or use the FluentValidation nuget package.
@zoran-horvat
@zoran-horvat Ай бұрын
@@ldeerosel I have skipped many small parts because they would obscure the principal message of the demo. However, in production code, you would have to install those back, so you are right. Anyway, those things do not affect what this video is demonstrating, in respect to persistence and value conversions with EF Core.
@gligom
@gligom Ай бұрын
I think that i start to cry, I realize that I am too stupid for such content. I see every day applications written with so much bad code, out off any principles, out of any patterns and out of common sense, but they work, are stupid simple and … they make money, not just now, for years. The developers just make them work, they don’t care about all the “theory”, they just do! And anyway for each principle, good practice, you will find 10 “experts” that will tell you why is bad to use.. One lesson that I learned, theory and tutorial examples don’t apply in real life applications.
@zoran-horvat
@zoran-horvat Ай бұрын
@@gligom Theory applies to practice but majority of practitioners don't know it.
@eugene5096
@eugene5096 Ай бұрын
dont cry, for 16 years + i also never saw and had no change to write something like this. Im trying Zorans approaches step by step in small pieces. In real life apps you would not need this or it will be done differently - its a reality.
@zoran-horvat
@zoran-horvat Ай бұрын
@@eugene5096 I strongly disagree with this opinion. It reminds me of people saying they don't need theory of algorithms, where in fact they don't know it. The reality is they miss the opportunity to apply it, for they don't know the opportunity even if it slaps them in the face, and then deliver sub par solutions. The same applies to database design or any other area of our expertise. You can know the theory, apply it, and deliver a superb solution. Or you can struggle with a solution that cannot handle the whole bunch of expectations and requests and blame whoever else, such as customers, users, managers, or the programming itself.
@ivanek333
@ivanek333 Ай бұрын
6:18 Why not just add two methods in IEdtition, for converting from and to the database? Isn't it, like, the whole point of abstraction? Overall, the solution seems like halfway to just straight json converting everything. And well, for some tasks it actually may be useful, but from my vague understanding, the advantage of having everything separate in the database (instead of just converting a whole object into a json string or whatever you're using) is the ability to grab only the required rows from the database, which is not possible with your solution (or it would require string processing in sql calls, with great potential for bugs and accidental breaks) One way it could work though, is that for each interface/abstract class/ you could also make an additional enum column in the database, which specifies the concrete type, and in your interface you can add another two methods for setting and checking if that enum value corresponds to this type. That way you keep all the benefits of abstraction (i.e. not changing orm-related code each time you add a new child class), but also have the ability to select rows with only those types that you need. 12:28 Oh, yeah, that's what i was talking about. 14:26, Well, developing my thought, you can also specify the return type in your interface (instead of just going all strings), so if you really want to harness the power of fitting everything to an int column, you can force child classes to convert their values to int too. (well, the one who would be forced to convert to int is the one implementing methods in child classes) Am I wrong?
@zoran-horvat
@zoran-horvat Ай бұрын
@@ivanek333 It is not a good idea to add persistence configuration to the interface, because that would require the interface to know the structure of all its implementing types and, worse yet, each implementing type would need to know the structure of every other. I thought it was a silly idea at first, but now I think it is a uniquely catastrophic idea.
@ivanek333
@ivanek333 Ай бұрын
@@zoran-horvat What do you mean? Why would "interface need to know the structure of all its implementing types"? Maybe I wasn't clear enough, because that's the opposite of what I was talking about. In interface you add two methods: string ConvertToDatabase(), and ISomeInterface ConvertFromDatabase(string value). And in those methods you implement those conversions you did at 7:41. And, I know, ConvertFromDatabase won't just work as simple as that, because to call it you need an instance of a class in the first place, so maybe you can work around by making it static and then register it somewhere else, and so on and on. My main point is that, the only reason you have abstraction tools is to do abstraction. If you have classes hidden behind interface, you shouldn't go and explicitly define mappings for each of them in some place, other than class itself.
@zoran-horvat
@zoran-horvat Ай бұрын
@@ivanek333 Give me the signature of the method on the interface that does the conversion.
@ivanek333
@ivanek333 Ай бұрын
@@zoran-horvat oh no, it seems like youtube had some error and didn't post my comment
@ivanek333
@ivanek333 Ай бұрын
probably it doesn't like links to pastebin?
@goliafffff
@goliafffff Ай бұрын
Looks interesting. But in real production application I will never ever do this. It's over complicated.
@zoran-horvat
@zoran-horvat Ай бұрын
@@goliafffff What would you do?
@goliafffff
@goliafffff Ай бұрын
​@@zoran-horvat Plain anemic model.
@zoran-horvat
@zoran-horvat Ай бұрын
@@goliafffff We've already been there. It is trendy to repeat mistakes of the past but, honestly, you won't impress anyone with that. Have you impressed anyone with that?
@liamhotspur9182
@liamhotspur9182 Ай бұрын
Think first, database first!
@zoran-horvat
@zoran-horvat Ай бұрын
@@liamhotspur9182 I strongly disagree. However, I'd say that database design remains as important as ever.
@liamhotspur9182
@liamhotspur9182 Ай бұрын
@@zoran-horvat Why? Because it is supposed to be more agile?
@zoran-horvat
@zoran-horvat Ай бұрын
@@liamhotspur9182 Database first? No. It's the opposite for all I am seeing in practice.
@robertmrobo8954
@robertmrobo8954 Ай бұрын
Ofcoz I liked the video content, but eish.. 🤦‍♂🥺
@zoran-horvat
@zoran-horvat Ай бұрын
@@robertmrobo8954 Was it too advanced, or...?
@JonathanPeel
@JonathanPeel Ай бұрын
And of course, you could use an event sourcing and never need to worry about how your domain model maps to a table.
@zoran-horvat
@zoran-horvat Ай бұрын
@@JonathanPeel First, it is not true. You will still maintain the schema for querying. Second, it is preposterous to assume that maintaining a relational schema is some kind of a problem. It is a solution to a problem, which requires work. Any other solution requires work, too. Not every system will benefit from event sourcing, naturally. Would you still apply event sourcing to an obviously relational problem? I generally dislike that tone which presumes event sourcing is a cure for all ailments. I can confirm that it usually comes from tragically incompetent programmers who don't even understand event sourcing, but needed something to run away from relational design which they also don't know.
@JonathanPeel
@JonathanPeel Ай бұрын
@@zoran-horvat I appreciate this reply 👍🏻 I am very happy in a relational world, a lot more comfortable than with a document DB. But that might be familiarity. The event sourcing is kind of the next technique I want to try to understand properly.
@shadowsir
@shadowsir Ай бұрын
For IEdition, I'd also keep a "discriminator" column (e.g. edition_discriminator or edition_type) to map the string value in the DB to the proper concrete class. Alternatively something like $"OrdinalEdition: {ordinal.Number}", $"SeasonalEdition: {Enum.GetName(seasonal.Season)} {seasonal.Year}", to keep it in a single column. This makes the conversion less "magic" as well. You never know if you're going to need a way to convert "1" to an OrdinalEdition or to a potential future type "AuthorDefinedEdition" where an author can enter any kind of string.
@zoran-horvat
@zoran-horvat Ай бұрын
You are right. I would go with a varchar + int columns, similar to PublicationInfo. One column would store the enum value or null, and the other would store the year number or edition number. That format is 100% deterministic.
@LuisPauloRSLima
@LuisPauloRSLima Ай бұрын
Thanks!
@zoran-horvat
@zoran-horvat Ай бұрын
Thank you!
@cristiz-vf4ww
@cristiz-vf4ww Ай бұрын
Thanks!
@zoran-horvat
@zoran-horvat Ай бұрын
Thank you!
C# Records Are Functional - Use Them That Way!
10:55
Zoran Horvat
Рет қаралды 14 М.
How to Avoid Null Reference Exceptions: Optional Objects in C#
18:13
Yay, My Dad Is a Vending Machine! 🛍️😆 #funny #prank #comedy
00:17
Walking on LEGO Be Like... #shorts #mingweirocks
00:41
mingweirocks
Рет қаралды 5 МЛН
Are You Accidentally Crippling Your EF Core Queries?
17:18
Milan Jovanović
Рет қаралды 29 М.
The Lesson About GUID IDs I Learned the Hard Way
15:43
Zoran Horvat
Рет қаралды 31 М.
Master the Design of Functional Types in C#
17:53
Zoran Horvat
Рет қаралды 17 М.
3 Implementations that will blow your mind 🤯
28:49
Next Increment
Рет қаралды 3,4 М.
You Can Now Track Record Types With EF Core
12:49
Zoran Horvat
Рет қаралды 6 М.
Master the Design of Functional Behavior in C#
19:17
Zoran Horvat
Рет қаралды 12 М.
Dependency Injection | Prime Reacts
28:34
ThePrimeTime
Рет қаралды 348 М.
"You're Doing Validation Wrong in .NET" | Code Cop #023
14:44
Nick Chapsas
Рет қаралды 37 М.
Yay, My Dad Is a Vending Machine! 🛍️😆 #funny #prank #comedy
00:17