📜 ⬆️ ⬇️

Inheritance in the ADO.NET Entity Framework

What are you talking about, Morpheus?


Greetings to all!
My first article on Habré was rated by Habrayuers rather high. Well, thanks to everyone who left their opinion on the article, I was pleased to read you, I continue.

In the new article I would like to talk about inheritance. Frankly, before studying the ADO.NET Entity Framework, I didn’t even think about introducing entity inheritance into object-oriented wrappers for the database into my projects. Usually the base was built so as to avoid inheritance as much as possible. Although, sometimes it loomed on the horizon, but it did. Now I will describe how I added to my project two very simple classes that were inherited from already existing tables.
')
Again, I note that I will not delve into the theory, I show everything in practice. For theory, I will do a separate series of articles.

So,

I will say right away. I spent an hour on the code, sorting out the mistakes that I had during the creation of this article. And my goal now is not only to show how ANEF inheritance is implemented, but also to show you typical errors that can be avoided.

By the way, implicitly agreed on this: ANEF = A DO. N ET E ntity F ramework

Here is my database.

Since the time of the first article, the structure of the database has changed a little, but still remains very simple. Initially, only two tables were present in the database: Post and User, now the scheme was a bit complicated

  1. I created a blogpost table. The meaning of this is that in my system, Post will be not only a blog post, but also a comment, a message, and generally everything that one user can transfer to another. Such a scheme is made solely for educational purposes. Because in most systems, comments are a very critical table, in which there are constantly many records, and which is the most loaded table in the system. Accordingly, the BlogPost should inherit all the data from the Post and carry additional information. I want the users themselves to write the name of the link to the comments under each blog post in my system. For example: "Plait here", "Think about it." It will bring some variety. Well, that, all my desires are well visible on the DB scheme. Here I will apply the first type of inheritance - each Entity has its own table.
  2. Also, it would be convenient for me to have simple User's and Admins in my database model. Therefore, using the IsAdmin field, I will do the second type of inheritance - one table for several Entity. By value in this field, the entity will be screened out.


Immediately make a reservation. Here I made my biggest mistake, which cost me 20 minutes of working with the forums. But in general, she was very stupid, and was made inadvertently.



Here in this screenshot are the correct arrangements of connections in the database. For the first time, I foolishly turned them around the other way, tobish I made a BlogPost Primary table in the link. Well, it happens, go further.

We go to the studio, to our database project and update our schema from the database. A new Entity BlogPost should appear. Everything is fine, it appeared. Even with the connection. Remove this link first. In inherited Entity we do not need it. After that - in the context menu of the Entity Post, we add a new inheritance. It turns out something like this:


And here, for the first time, I caught up with the frustration of the visual development environment. We start the validation of the project (I recommend to run this validation almost after every sneeze, if you are not completely familiar with the work of inheriting ANEF). And validation falls with a bang. The trouble is that we need to tinker a little more and understand something before we can properly manage inheritance.
We have two tables: BlogPost and Post. There are two keys in the tables: BlogPost.PostId and Post.Id, this is what SQL considers. ANEF quite correctly believes that in fact, the BlogPost table does not have the BlogPost.PostId key, but the Post.Id key. In principle, this is more than logical, we have a 1: 1 relationship, so why do we need to bother with another key? It is truth too. Remove the PostId parameter from the Entity BlogPost. After that, the validation crashes again. Also correct. We have a PostId value in the table, but it has no mappings. We fix this bug:



We set the mapping for the PostId table field to the Id variable. The question immediately arises, and where we managed to determine the Id variable for the BlogPost table. As I said before - ANEF believes that Entity Post and BlogPost have only one key, therefore implicitly added it to the BlogPost table. As a result, our final Entity looks like this:


Everything seems, now it can be used. Try compile.
This was the first type of inheritance we analyzed. Each Entity is bound to its table in the database. Now let's move on to the second type of inheritance, where we have only one table, and several types of Entity.

As I said before - I wanted to separate Entity Admin from User. With ANEF, this is easy enough to do. Through the context menu, add a new Entity, while indicating that it is inherited from the Entity User. You can immediately remove the IsAdmin property from the entity User and from the Admin, I have it left for clarity, but with it you will not pass validation. In short, this is the first approximation of our inheritance:



Again you need to conjure a little. First, you need to set up the mapping conditions. In particular, we now have all the User and all the Admin are the same, nothing separates them. Go to the entity mapping and select the conditions under which the mapping should take place:


Here I have already deleted the IsAdmin field, which is unnecessary for us; moreover, ANEF does not allow us to transfer this field to a variable, since it is a mapping condition. Well, we have admins, and what will be in the table of users? That was another cool mistake. I climbed the forums for another five minutes, until a fairly simple fact reached me: if we, by any condition, filter records into the Admin table, this does not mean that all other entries will automatically go to the users table. Therefore, it is necessary in the mappings of the User table to also include a condition and filter out the remaining entries in this table.

Immediately make a reservation, I have the IsAdmin field, despite the name, not Boolean, but Int16, so the screening was carried out according to the principle IsAdmin = 1 and IsAdmin = 0, later we had the idea to expand the administration capabilities, so it was taken for the future .

Well, we have formed two very simple, but still inherited entity. Which properties and how to inherit is not important. You can experiment with it yourself. My goal was to show exactly how to carry out this inheritance. Done To start.

I can only notice this. While I was digging into the ANEF inheritance, I figured out several schemes, the implementation of which would really be facilitated using inheritance. For example, in one of our systems there was a system for working with a portfolio, where a person could enter various data about himself, such as: place of work, education, scientific publications, etc. For each of the record types in the portfolio there was a separate table, and I can tell you for sure - the SQL query that selected this data was just hellish. Everything was very uncomfortable and crooked. If I then used inheritance, then I would have a List <> of base classes, for example, PortfolioEntry, with which I could work quickly and conveniently. This is an example from life, I think, having picked the insides of the ANEF, you yourself will find many such examples in your code.

In the next article I will try to provide more software code that will show how to work correctly with the inherited entity.

PS It’s boring to write yourself a system. So I thought, why not invite Collective Intelligence to yourself, and do not consult with him about all this. It is assumed that next Saturday I will be able to invite two or three interested people with me, with whom it will be possible to torment ANEF on an equal footing, conduct tests, write code and describe a theory. I'm just not keeping track of everything. At the end of a three to four hour event, participants will receive a free beer. If someone is interested in such group tests - write in a personal, we will think through.

PPS All this was done on free versions of Visual Studio and Management Studio. Microsoft is not the most brutal way to cut its products.

Source: https://habr.com/ru/post/47395/


All Articles