|
Doh! I'd hoped I was wrong.
|
|
|
|
|
I thought it might be celebrity - but had no idea how to get there!
|
|
|
|
|
It's a bugger when that happens, isn't it?
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
And how it just does not work with interfaces or base classes. At least, I can't get it to work, so maybe I'm stupid.
Doing some googling, there's things like HasBaseType that have to be manually coded in the OnModelCreating method, or in the query, potentially using .Include , but really.
Why can't it just figure out what to do based on the class structure?
Maybe it's me. But I can understand why people use Dapper.
|
|
|
|
|
Personally I like to keep it simple and straightforward, i.e. 1 table => 1 class.
i.e. no hierarchy, interface, etc...
Works for me! ^_^
You could argue I am ignoring many powerful features... and you would be right! But it works out quite well for me anyway!
|
|
|
|
|
Maybe you'll get a mail someday that starts with "I have been maintaining your code for a decade now, and I really HATE you!" 
|
|
|
|
|
That's fine, I get a lot of positive comments, so I can look at the negative ones in a funny way!
|
|
|
|
|
Quote: I have been maintaining your code for a decade now, and I really HATE you!
IMHO: If you work for a decade doing plain CRUD, without automating the process, you should probably look for a different profession …
Espen Harlinn
Senior Architect - Ulriken Consulting AS
The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.Edsger W.Dijkstra
|
|
|
|
|
I'm trying to implement a certain degree of abstraction, especially for REST calls, where the entities (tables) are passed in as part of the route and I want CRUD methods that are abstracted so I don't have to write unique code for each context entity.
My problem is one of laziness - I know how to do this in different ways, thought I'd see how one might do this with EF, but I'm too lazy and impatient to figure out what hoops, canyons and mountains I have to jump through, create a bridge over, or climb with enough oxygen tanks, to get it to work.
Maybe I'll google some more.
|
|
|
|
|
I never used oData.. but it looks like LinQ 2 SQL code over WebAPI, could it be something that would be useful to you?
And I remembered being excited about it... but then, in some context it's doomed to obsolescence because exposing the DB is often a no-no.. But it's a god send me think for SPA or private phone apps...
Anyway, if you are curious, here is a link:
OData documentation - OData | Microsoft Docs
modified 22-Mar-21 9:46am.
|
|
|
|
|
Agreed. Frameworks are great if you're solving the same problem as the framework developers. If you're trying to solve something else they're a waste of time.
|
|
|
|
|
EF entities (classes) can have interfaces; used as a base class; and can be composed of partial classes.
The EF "model" understands tables, entities, and related functions; not specific language features.
The (basic) "table" is in fact a "base" class candidate; while a view is a single or multi-table "interface" of selected columns.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
Clearly EF is not everyone's cup of tea, but I think things could be worse e.g. when you would have to use NHibernate
Here is an overview of some alternative ORMS[^]
|
|
|
|
|
You mean it should create tables based on your inheritance structure?
EF can deal with regular inheritance and interfaces just fine, I guess it kind of ignores it.
But if you have a class, say Employee, that inherits from Person, a migration won't magically create two tables with Employee having only the Employee specific properties and a reference to Person.
I put everything in OnModelCreating (like types, nullable, etc.).
Just because you're using an ORM doesn't mean you don't have to think about your DB structure anymore
|
|
|
|
|
Sander Rossel wrote: You mean it should create tables based on your inheritance structure?
Nah, I don't want EF creating anything. I just thought I'd try using it, but I want control over the inheritance structure and leave it to my responsibility that the fields defined in the base class are implemented in the table that mirrors the derived class. Seem that it doesn't like that.
|
|
|
|
|
I've never had an issue with that...
However, I use my entities as just that, entities.
"Dumb" classes that do nothing except hold some data.
Whenever I want to do something, anything, with that data, I create a model class.
I've worked with entities before and it always comes back to bite you (lazy loading, then NOT lazy loading, circular references, etc.).
|
|
|
|
|
Using base classes to define common properties for multiple entities just works, in both EF Core and EF6. For example, I often use a TrackedEntity class:
public abstract class TrackedEntity
{
public DateTimeOffset CreatedDate { get; set; }
public string CreatedBy { get; set; }
public DateTimeOffset? UpdatedDate { get; set; }
public string UpdatedBy { get; set; }
}
public class Foo : TrackedEntity
{
public int Id { get; set; }
...
}
public class Bar : TrackedEntity
{
public Guid Id { get; set; }
...
} Each table will have the properties from the base class.
If you want more complicated things, there's always Table-per-Type or Table-per-Hierarchy options:
Inheritance - EF Core | Microsoft Docs[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hmmm, I think when I was testing this, my failure was in declaring the base class as abstract. Like I said, I might be being stupid.
|
|
|
|
|
Good to know. At first I was worried it might have been a feature lost during the move from EF6 to EFcore.
I'd seen the partial class trick used to apply interfaces/base classes once before; naturally it was about a year after I'd worked on a different project where knowing the feature was available would have let me take a copy/paste code reduction from ~90% to ~98% fewer lines for the segment I was completely rewriting.
Did you ever see history portrayed as an old man with a wise brow and pulseless heart, weighing all things in the balance of reason?
Is not rather the genius of history like an eternal, imploring maiden, full of fire, with a burning heart and flaming soul, humanly warm and humanly beautiful?
--Zachris Topelius
Training a telescope on one’s own belly button will only reveal lint. You like that? You go right on staring at it. I prefer looking at galaxies.
-- Sarah Hoyt
|
|
|
|
|
Are you using Database first or Code first?
|
|
|
|
|
Database first, but then I learned that .NET Core 3 / EF doesn't support creating the C# model from the DB model unless you use Scaffold-DbContext from the Package Manager console, and it's a bit stunted. It's annoying that the tooling doesn't implement enough flexibility, but that's par for the course.
|
|
|
|
|
I never use EF -I learnt it and decided my own BL/DataAccess model was better and much more flexible. I have a base BL which has its own connection class and I can get a new project CRUDABLE in a very short time. I understand why people use it but it's not for me.
"I didn't mention the bats - he'd see them soon enough" - Hunter S Thompson - RIP
|
|
|
|
|
Quote: But I can understand why people use Dapper
It will still underperform compared to using the drivers directly - which, as we all know, isn't all that hard.
Espen Harlinn
Senior Architect - Ulriken Consulting AS
The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.Edsger W.Dijkstra
|
|
|
|
|
|
So I figured out awhile ago how to prepare a massive amount of information about a pixel format based on a few inputs about it, where the compiler computes the rest at compile time. It's all powered by C++ templates. It implements code, to for example, shift a 6 bit value out of the middle of a 16 bit big endian word, give it you you, and then allow you to change it.
You define the bit depth of every channel, and what type of channel it is, and it does the rest:
using rgb565be = pixel<
color_model::rgb,
endian_mode::big_endian,
channel_traits<channel_name::R,5>, channel_traits<channel_name::G,6>, channel_traits<channel_name::B,5> >;
and then you can get the channel info from a pixel type like this:
using ch = typename PixelType::channel_type_by_index<Index>;
printf("channel %s\r\n",ch::name_());
printf("\tindex: %d\r\n",(int)ch::index_);
printf("\tbit-depth: %d\r\n",(int)ch::bit_depth_);
printf("\tmin: %llu, max: %llu\r\n",(unsigned long long)ch::min,(unsigned long long)ch::max);
printf("\tscale: %llu\r\n",(unsigned long long)ch::scale);
printf("\r\n");
It computes all those values above (the trailing underscores are to avoid conflicts with virtual instance methods of the same name that allow you to get the information at runtime rather than compile time like above)
Pretty slick, if I do say so myself, but...
I want to be able to automatically generate code to convert pixel formats of the same color model to each other, so you can for example, from 24-bit RGB to 16-bit BGR format without missing a beat or writing code to do it yourself.
So I needed a template to fetch a channel by name at compile time.
I can get it, but I can't populate the index of the channel with a meaningful value if I don't retrieve it by index. Nor can I count the bits to the left of it which means that nifty shifting code I generate is incorrect if I fetch the channel type by name.
I'm stumped by the seemingly simple task of convincing the C++ compiler to give me the index of type (within a template argument parameter pack) that has a particular string associated with it.
I've been working on this all day.
I love C++.
I hate C++.
Real programmers use butterflies
|
|
|
|
|