Adding DateTime field to many-to-many EF Code First relationship - entity-framework

I am using EF 6 Code-First, table per type, and I have two concrete classes Group and User. Group has a navigation property Members which contains a collection of User. I have mapped this many-to-many relationship in EF using Fluent syntax:
modelBuilder.Entity<Group>
.HasMany<User>(g => g.Members)
.WithMany(u => u.Groups);
I would like to be able to say when a member has joined a group so that I can query for, say, the newest member(s). I am not sure of how this is best accomplished within the framework.
I see the following options:
Create and use an audit table (ie GroupMembershipAudit consisting of Group, User, join/unjoin, and DateTime
Add a column to the autogenerated many-to-many table between User and Group
Is there anything within EF to facilitate this sort of storage of many-to-many historical info like this / append columns to the many-to-many relationship?

Add a column to the autogenerated many-to-many table between User and
Group
That is not possible - auto-generated junction tables can contain only keys (that is called Pure Join Table). According to Working with Many-to-Many Data Relationships article: If the join table contains fields that are not keys, the table is not a PJT and therefore Entity Framework cannot create a direct-navigation (many-to-many) association between the tables. (Join tables with non-key fields are also known as join tables with payload.)
Create and use an audit table (ie GroupMembershipAudit consisting of
Group, User, join/unjoin, and DateTime
Actually you should create GroupMembershipAudit entity. With Code First table will be generated, you don't need to create it manually.

Related

Entity Framework 6 - Inserting/Updating 2 table joined by a view

In my database I have
a Members table which contains basic member details (MemberId [primary key - auto generated number], MemberName, IsActive).
a MembersDetails table which contains more detailed information about the member (Address, Phone, Birthday ...). MembersDetails has MemberId field as a foreign key to the Members table.
There's a reason (part of the app logic) that the 2 tables are separated and are not all in one table.
I've created a view that gets a full member details (a join of the 2 tables), and Entity Framework created an object that represents the view.
I have 2 questions:
Is there a better way of flattening 2 joined tables into an object other than creating a view in the database?
I would like to create an object of the view type (a full user details), initialize it's properties and insert it to the database (which will put the info it needs in the Members table, the the generated id, and than insert to the MemberDetails table). Is there a way to do that?
Ad 1.
I think a database view will be a good choice for performance reasons.
But you can investigate an inheritance provided with the Entity Framework.
It allows you join two separated tables in one model object containing all properties (from "derived" and "base" table). Note, it will be OK for one to one relations (but not for one to many).
Implementing Inheritance with the Entity Framework 6 in an ASP.NET MVC 5 Application
Ad 2.
The Entity Framework inheritance will help you with this issue well. Alternatively, if you can use a database view, just create stored procedures for inserting and updating data included in a view, then map the stored procedures for specified actions on the view model generated by Entity Framework.

JPA Multiple relationships on one field in an entity

I am a beginner to using JPA 2.0 and databases in general and I was just confused about a few concepts.
So I have a total of 3 tables. One is the UserTable, which contains all the information about my user. It has a primary key field called user_Id. My other two tables are ExercisesTable and FoodIntakeTable, and they each have a foreign key field called user_Id to reference the user_Id in my UserTable. I want a one-to-many relationship from my user_Id table to each of the two tables so I can find pull out exercise information or food information for a user.
Pretty much like this:
FoodIntakeTable <-> UserTable <-> ExercisesTable
I need a bidirectional mapping from UserTable to FoodIntakeTable and also a bidirectional mapping from UserTable to ExercisesTable from the field user_Id.
The problem is, when I try to write my code like this in my Usertable class:
#OneToMany(mappedBy="ExercisesTable.userId")
#OneToMany(mappedBy="FoodIntakeTable.userId")
public long userId;
It's illegal because I can't have two #OneToMany annotations on the same field. I think it's supposed to be legal in a normal relational database and I'm just confused about how you translate this into JPA. I'm very new to the whole concept of databases and entities in general, so any help would be appreciated.
In JPA you can directly reference entity objects instead of the ids that they are mapped by. Try something like this:
You should have an entity type for each of your tables, say Exercise for ExercisesTable, FoodIntake for FoodIntakeTable, and User for your UserTable.
Then your User entity is the owning side of the relationships, having one field per relationship like this:
#OneToMany(mappedBy=...)
private List<Exercise> exercises;
#OneToMany(mappedBy=...)
private List<FoodIntake> foodIntakes;

The Many To Many relation will not be mapped when using ADO.net entity framework

I have these three tables inside my sql server but when mapping these tables using EF I will lose the table representing the M-M relation -the accountsitemapping table- and in this case I will not be able to know which accounts are linked to which sites.
To workaround this problem I just added a new column to the AccountSiteMapping table and I re-mapped the tables again then I can access the AccountSiteMapping table.
But is there a way to be able to solve this problem without the need to modify my table design ?
By default entity framework will hide all mapping tables in many-to-many relationships. You will have to do your queries this way:
For example, finding SiteDefinitions associated with a given org_ID:
db.SiteDefinitions.Where(a => a.AccountDefinitions.Any(b => b.ORG_ID == org_ID));

How can I replicate core data model using a traditional relational database?

I have my app using core data with the data model below. However, I'm switching to a standard database with columns and rows. Can anyone help me with setting up this new database schema?
First of all you need to create tables for each of the Entities and their attributes (note I added "id" to each of the tables for relationships):
Routine (name, timestamp, id)
Exercise - this looks like a duplicate to me, so leaving one only here (muscleGroup, musclePicture, name, timeStamp, id)
Session (timeStamp, id)
Set (reps, timeStamp, unit, weight, id)
Now that you have tables that describe each of the entities, you need to create tables that will describe the relationships between these entities - as before table names are in capitals and their fields are in parenthesis:
RoutineExercises (routine_id, exercise_id)
SessionExercises (session_id, exercise_id)
ExerciseSets (exercise_id, set_id)
That's it! Now if you need to add an exercise to a routine, you simply:
Add an entry into Exercise table
Establish the relationship by adding a tuple into RoutineExercises table where routine_id is your routine ID and exercise_id is the ID of the newly created entry in the Exercise table
This will hold true for all the rest of the relationships.
NOTE: Your core data model has one-to-many and many-to-many relationships. If you want to specifically enforce that a relationship is one-to-many (e.g. Exercise can only have 1 routine), then you will need to make "exercise_id" as the index for the RoutineExercises table. If you want a many-to-many relationships to be allowed (i.e. each exercise is allowed to have multiple routines), then set the tuple of (routine_id, exercise_id) as the index.

EF: How to eliminate a joi-table in the model while still respecting relationship among tables in the underline database?

Let's say I have a Database with 3 tables: Keywords, Documents, and KeywordDocuments. KeywordDocuments has only 3 columns, KeywordDocumentID, KeywordID, and DocumentID.
The relationship between Documents and KeywordDocuments is the same as Keywords and KeywordDocuments, i.e. one-to-many.
Watching Julie Lerman's video on EF, she said that we don't need KeywordDocuments's entity in the model. How do I eliminate that entity while making sure that in the relationship will be respected in the underline database?
Thanks for helping
Remove the KeywordDocumentID column from the KeywordDocument table. It will then contain only the foreign key columns from the tables for which it represents a many to many relationship.
Create a new composite primary key on the KeywordDocument table which includes both the KeywordID and the DocumentID columns. This will replace the original primary key that you had on the KeywordDocumentID column - that key would have been deleted along with the column.
A table such as this will not result in an entity being generated in the model. Rather, both of the other entities (Keyword and Document in this case) will have navigation properties based on EntityCollection. Document will have a collection of Keywords and vice verca.