I have created my Database which has:
Artist, tracks and TracksPerArtists
I can do sql queries through the entity model. For example when I make:
database.TRACK.ToList()
I get the list of track to be shown on index view for example. But my foreign keys come empty. While there is an artist and a track, and the correct row for ArtistsPerTrack, this item in my track.ToList() collection is empty.
Is there a different way to fetch those data?
I came from cakePHP framework in which you can define the Model.recursive property to declare the depth of the relations you want to fetch.
Is there anything similar here?
There is something similar.
If "database" is DataContext and Artist and Tracks have many to many relationship in database, you can fetch related entities using Include clause:
database.TRACK.Include("Artists").ToList()
where "Artists" is the name of property on Track entity.
Related
I have an asp.net MVC solution, Entity Framework code first, which has dozens of database tables all designed around a single company using the solution.
The requirement has come up to allow multiple companies to use the solution, so what we have done is add "CompanyID" as a column to all database tables and set a default value. There is a company table with the various company names and CompanyID's. On login the user selects the company they are logging in as which stores the CompanyID in the session.
At the moment every Entity Framework call now has to be updated to include the CompanyID, for example when selecting Employees I am doing:
List<Employee> employees = db.Employees.Where(x => x.CompanyID = Session.CompanyID).ToList();
As you can see it will be tedious to do this on thousands of calls to the db. Any update, save, and fetch has to change.
Surely I am doing it the long way and there is a way at runtime, globally to append all DB calls to include the CompanyID stored in the logged in users Session? Something that dynamically appends the CompanyID when fetching values or storing etc? Perhaps a package I can use to do this task at runtime?
In my opinion, there is no need to add CompanyID to EVERY table in the database. I would select just "root" tables/entities for that. For example, Employee or Department clearly sounds like a many-to-one relationship with a company - so adding CompanyID there sounds right. But, for example, EmployeeEquipment which is a many-to-one relationship with Employee does not have to have CompanyID column since it can be filtered by the joined Employee table.
Regarding your request to filter by CompanyID globally, I'm not aware of anything that can do that per request. There are global filters for Entity Framework, but I'm not sure how you can apply them per-request. Take a look on .HasQueryFilter() during model creation if you are using Entity Framework Core.
I have several entities, that can have multiple relationships.
For example, i have following entitites:
entity_type
tag
tag_assignment
news_post
account
In entity_type table are described all entities that i have in my project (e.g. news posts, blog posts, messages, accounts, everything)
Entity_type table has just id and name fields, name field describes model class name for usability
Tag entity has just id and name. It's standalone entity, that is mapped to other entities later with tag_assignment entity
Tag assignment entity has id, tag_id, entity_type_id and entity_id. Entity_type_id describes in which i can find entity, entity_id specifies entity in the table.
So i want to make following combined foreig key from one column to many tables:
tag_assignment.entity_type_id => entity_type (id)
tag_assignment.entity_id => news_post (id), account (id), etc
Is it possible to make this combined key? I mean if to make dependencies if i delete a row from entity_type table, everything will be dropped/updated in other tables, if i will delete account, only tag_assignments that have foreign key to account table will be deleted.
You should normalize your database by extracting a table called entity. The concept of this table is similar to an abstract class in OOP. The news_post, account and other entities you might have in your database should all reference the entity table. This way you can reference any entity that you have now or might have in the future with a common, specific location.
Also you might want to familiarize yourself with the EAV model. This might help you resolve similar design issues.
Am I missing a point with Doctrine? It's been very useful for some scenarios, but for the basic scenario of retrieving an entity using an Id (say using find() or findOneBy()) why do you see a query being fired off for every relationship to populate the main entity's properties?
Surely with the mapping/annotations I've created, Doctrine should be capable of a few joins and one query, without having to write a DQL query for the retrieval of each entity.
Or, as I'm predicting, have I missed the point somewhere!
Just add the aliases of related entities to select part of your query.
Let’s say, you have Book related one-to-many to Cover, and you want so select some books with their covers.
With query builder, use:
->createQueryBuilder()
->select("book, cover")
->from("Book", "book")
->leftJoin("book.covers", "cover")
With query, use:
SELECT book, cover FROM Book book LEFT JOIN book.covers cover
As the result, you will receive collections of Book with prepopulated $covers collection.
Because the relationships are hydrated only when needed - by default Doctrine uses a lazy-loading strategy.
If you already know that you will access the related entities, you should build a DQL query that retrieves the record AND the related entities.
I have a fluent nhibernate configuration in my app. Running latest of both. I am trying to create a criteria statement to pull back a specific class in a joined subclass hierarchy. This is an example of my inheritance structure:
Admin is an Employee is a Person (Admin : Employee, Employee : Person)
What I am trying to get is the Employees but not the Admins, but since admins are employees, they are coming back in the query. I do not have a discriminator column to use. Is there any way to accomplish this using the Criteria API?
Thanks in advance.
Schema as requested (just an example):
Person table: Id, Name
Employee table: PersonId, EmployeeNumber
Admin: PersonId, AdminNumber
NHibernate relates those properly. Everything else works except this specific type of query.
It appears that Criteria does not support that functionality. I was able to solve the issue by adding a SQL Restriction to the query to filter out the subclass results.
criteria.Add(
Expression.SQL("{alias}.MyPrimaryKey NOT IN (SELECT MyPrimaryKey FROM Admin)"));
This essentially excludes and results from the Employee SQL query where that Employee exists in the Admin table, thus returning only Employees that are not Admins.
I originally tried separately querying the Admin table via Criteria to get a list of Ids which I then fed into the Employee query using a NOT IN Criteria statement Restrictions.Not(Restrictions.In()) but SQL Server restricts the number of parameters to 2100 and blows up if that collection of Ids that you are trying to exclude has more than 2100 items.
I have 3 tables(Roles,Actions and RoleActionLinks). Roles table has few columns(RoleID,RoleName,Desc). Actions table has few colums(ActionID,ActionName,Desc). In RoleActionLink is created for store the association between Roles and Actions and this table has the columns such as RoleID,ActionID
When I created the data model(edmx). it shows only Role and Action as entity. i did not find RoleActionLink table. but even there is no direct relation between Roles and Actions table, both tables are automatically related using RoleActionLink table.
When i create the new Action, a action record should be populated in Action table(this is works fine). At the same time, i need to populate record in RoleActionLinks table. But i dont have the entity to populate.
Please tell me how to accomplish my needs.
This should work:
newAction.Roles.Add(role1);
newAction.Roles.Add(role2);
Look at navigation properties in your model. There should be EntityCollection called Roles (name may differ).
Entity framework automatically handles n-n tables and creates collections on both sides.