Entity Framework - How to Insert to table with foreign keys without retrieving foreign table rows first - entity-framework

I'm having a hard time finding the exact answer to this question, so my apologies if this is redundant.
So I have 3 tables defined such that:
Person :PersonId, FirstName, LastName
Company: CompanyId, CompanyName
Order: OrderId, PersonId, CompanyId
On the Order table, there is a foreign key defined on the PersonId and CompanyId columns, thus, my Order entity class generated by EF has a navigation properties of type Person (not PersonId) and Company.
So, to insert into the Order table, I first need to query the person and company tables to get the person and company entities. Then I can construct the Order object using the Person and Company entities and save it to the db.
In my scenario, I am being passed a PersonId and CompanyId.
In classic SQL I would just do INSERT INTO Order Set (CompanyId, PersonId) - 1 database call. But with EF, I have to do 3 db calls. This seems like overkill.
Is there any way around this?
PS - I'm using EF 6. I know I could generate an expression and make it single call..but that would still yield two subselects.

You can just include foreign key properties in addition to the navigation properties and then set them using the ids you have. If you do this will not have to go to the database to get related entities for just a sake of setting the relationship.

Related

How to use Entity Framework 6 to update many-to-many relationship?

Someone else asked a similar question here: How can I use EF6 to update a many to many table
I mention that up front because I couldn't get any of the solutions given to work.
I also studied the solution give on Code Project: http://www.codeproject.com/Tips/893609/CRUD-Many-to-Many-Entity-Framework, but this doesn't work for me either.
I'm trying to keep this as simple as possible.
I have two tables: dbo.Teacher and dbo.Student. Each has an "ID" column that servers as a primary key. I also have a third table called dbo.StudentTeacher which has exactly two columns, both are non-nullable and foreign keyed to the previous two tables; in other words, it establishes a many-to-many relationship between teachers and students. As expected, the EDMX designed shows only dbo.Student and dbo.Teacher and infers the relationship between them.
Here is a script for the above; there is nothing else in the database.
CREATE TABLE dbo.Teacher
(
Id INT NOT NULL PRIMARY KEY,
Name VARCHAR(MAX)
);
CREATE TABLE dbo.Student
(
Id INT NOT NULL PRIMARY KEY,
Name VARCHAR(MAX)
);
CREATE TABLE dbo.TeacherStudent
(
TeacherId INT NOT NULL FOREIGN KEY REFERENCES Teacher(Id),
StudentId INT NOT NULL FOREIGN KEY REFERENCES Student(Id)
);
INSERT INTO Teacher(Id, Name)
VALUES
(101, 'Tom');
INSERT INTO Student(Id, Name)
VALUES
(201, 'Sue'),
(202, 'Stan');
INSERT INTO TeacherStudent(TeacherId, StudentId)
VALUES
(101, 201);
Now that I've established my data structures, I want to accomplish a very simple task. From the script above, you can see that we have one teacher named "Tom" who has a student named "Sue". We also have a student named "Stan" with no teacher. My task is to modify the database so that Sue is no longer Tom's student and Stan becomes Tom's student.
To accomplish this, I wrote the following code:
class Program
{
static void Main(string[] args)
{
using (var entities = new TestEntities())
{
// There is only one teacher in the system.
Teacher teacher = entities.Teachers.Single();
// This teacher has a student #201: Sue.
// I want to replace her with student #202: Stan.
teacher.Students.Clear();
teacher.Students.Add(new Student() { Id = 202 });
entities.SaveChanges();
}
}
}
It looks very simple: clear the students associated with Tom and then add Stan as Tom's student. However, when I run the code, I get the following error: Unable to update the EntitySet 'TeacherStudent' because it has a DefiningQuery and no <DeleteFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.
I tried simplifying the problem by trying to just remove Sue from being Tom's student without adding Stan, and I get the exact same error message.
As I understand, this error normally occurs when Entity Framework doesn't have enough information to do what you want it to do, but I really can't see what's missing. There are two simple tables with a join table between them and I need to be able to change which rows are related to which other rows.
I should also note that if I'm not mistaken, the change that I wish to make in this example should affect only the dbo.TeacherStudent table; the other two tables should not be touched.
Okay, after some more Google-Fu, I figured it out.
Even tho the join table must have only two columns with each column foreign keyed to the two tables to be related, the join table still needs a primary key, which can be a composite of the two foreign keys.
Thus, dbo.TeacherStudent should be created with this:
CREATE TABLE dbo.TeacherStudent
(
TeacherId INT NOT NULL FOREIGN KEY REFERENCES Teacher(Id),
StudentId INT NOT NULL FOREIGN KEY REFERENCES Student(Id),
PRIMARY KEY(TeacherId, StudentId)
);

Map tables relationship from legacy database w/ entity framework with only primary keys

data (table name)
dataid PK,
value1,
value2,
value3
data_address (table name)
dataaddressid PK,
dataid - id to errenddataid,
addressid1 - id to en addressid,
addressid2 - id to en addressid,
type
address (table namne)
addressid PK - id to addressid1 or addressid2,
address1,
address2,
name,
zipcode,
city
I have a really hard time trying to map this relations using Entity Framework 5, if some one have an idea or good links I would much appreciate that!
If you are certain that the database's integrity is sound you could just map the tables and create the associations manually in the EF model.
In a database-first mode I fiddled a bit with a simple data model: Parent + Child without FK. The tables were of course imported without association between them. Then I did "Add Association..." on the Parent, like so:
Note: no foreign key property yet. I added it manually in the properties of the association:
And I could run a linq query on Parent.Children.
I think this is the easiest way for you. The edmx design surface gives you some guidance to see which associations you created. You can always add a code generation item to generate a DbContext which is easiser to work with than the default ObjectContext.

Entity Framework table per type inheritance with PK->FK, not PK->PK

I have to create an entity framework model for a badly designed database. The database uses table per type inheritance but it does so with using a PK->FK relationship, not a PK->PK relationship. E.g.
Person
PersonID (PK)
Name
Employee
EmployeeID (PK)
PersonID (FK)
DateStarted
HourlyEmployee
HourlyEmployeeID (PK)
EmployeeID (FK)
HourlyRate
Obviously this is just badly designed, but I can't change it. Table per type inheritance in the entity framework essentially wants EmployeeID not to exist and the PK for Employee to be PersonID. Is it possible to create a model for this database, or do I choose another tool? any recommendations?
You will not map this as TPT inheritance because your database is configured in the way that doesn't allow you cheating EF.
If Employee.EmployeeID is auto-generated in the database and Employee.PersonID is unique (uniqueness must be enforced in the database) you should be able (not tested) to cheat EF by simply mapping:
public Employee : Person {
public DateTime DateStarted { get; set; }
}
This class will tell EF that Employee inherits key from Person (PersonID) and you will hide the real key from EF - this should work if the real key is auto-generated.
The problem is your next level of inheritance which breaks this pattern. To make this work your HourlyEmployee will have to reference PersonID - not EmployeeID. EF now doesn't know about EmployeeID existence so it even cannot map relation with HourlyEmployee.
TPT inheritance in code first has one additional limitation - PK column must have the same name in all tables.
You can create a model from the database if it exists but it might not be what you expect. EF sometimes doesn't work that great with weird database structures.

Need help with Entity Framework Relationshipships

I'm new to Entity Framework and just experimenting...
Consider 3 db tables where Person is a base table. I want the Employe table to enherit from Person, storing employee specific info. It seems that EF requires that PersonId also be the PK of the Employee table, so I made EmployeeID a unique index.
Next I added a table, Application, which stores one record for every software application that the Employee supports, creating a foreign key from Application.EmployeeId to Employee.EmployeeId.
However, EF doesn't seem to recognize relationships that involve unique indexes, but only Primary Keys.
What I can do is create a relationship from Application.PersonId to Person.PersonId, however, only Employees can be responsible for an Application, so it seems more natural to me to have Application as a "child" of the Employee table rather than the Person table.
Is this possible in EF?
You can build your relation between Employee (PersonId) and Application (EmployeeId). In such case the integrity should work as you expect because only PersonIds in Employee table will be only for existing employees. EF has currently no support for unique keys.

Entity Framework Association with Non Key fields

Is it possible to create associates b/t 2 non-key fields in the Entity Framework?
Example: Take the 2 tables in a legacy application (i.e. keys/structure cannot change)
Order (
OrderId : int : PK
OrderNo : varchar
)
OrderDetails (
DetailRecordId : int : PK
OrderNo : varchar
)
In the Entity Framework, I want to create an association b/t Order and OrderDetails by the OrderNo field, which is not a primary key on either table or a FK relationship in the database.
This seems to me as not only should it be easy to do, but one reasons to use something like EF. However, it seems to only want to allow me to create associations using entity keys.
The Entity Framework allows you to claim that columns are keys and that FK constraints exist where none actually exist in the database.
That is because the SSDL (StorageModel part of the EDMX) can if necessary be manipulated by you and lie about the database.
The EF will then interact with the database as if the keys and foreign keys really do exist.
This should work, but all the normal caveats about referential integrity apply.
See my Entity Framework Tips
Hope this helps.
The problem with using non-key fields to define relationships is that the keys are not guaranteed to be properly navigatable. That could lead to a situation where you have a one to one relationship between two entities where there are more than one possible rows that fufill the relationship.
...when relating data from a database, the relationships should always be based on keys. The keys enforce the referential integrity.
One more workaround:
create view vOrder which will not include PK and create Entity from it.
Set PK in this entity to OrderNo
Now you will be able create association