Many-to-Many insert failing - Entity Framework 4.1 DbContext - entity-framework

I am using DB first method, EF 4.1 with DbContext POCO code gen.
My database has a many-to-many relationship as shown below:
Employee
EmployeeId
EmployeeName
Account
AccountId
AccountName
EmployeeAccount
EmployeeId
AccountId
The problem occurs when I am trying to insert a new Employee, and assign them a pre existing account, so I am basically doing this as below:
Employee emp = new Employee();
emp.EmployeeName = "Test";
emp.Accounts.Add(MethodThatLooksUpAccountByName("SomeAccountName"));
context.Employees.Add(emp);
context.SaveChanges();
The SQL this is executing (incorrectly), is attempting to INSERT a new [Account] record, and this is failing on a constraint violation. Of course, it should not INSERT a new [Account] record, it should only insert a new [EmployeeAccount] record, after inserting the [Employee].
Any advice? Thanks.

MethodThatLooksUpAccountByName does this method return an attached or detached object? In any case, you may try to attach the object it returns to the context.
Employee emp = new Employee();
emp.EmployeeName = "Test";
var acc = MethodThatLooksUpAccountByName("SomeAccountName");
context.Attach(acc); //I don't remember if it's attach or attachobject, but intellisense should help you there.
emp.Accounts.Add(acc);
context.Employees.Add(emp);
context.SaveChanges();

Related

Get Record ID in Entity Framework 5 after insert

I realize this must be a relatively simple thing to do, but I'm not getting what I'm looking for with Google.
I need to get the record ID of the record I just saved using the Entity Framework. With SQL queries we used "Select ##IDENTITY as 'Identity';"
If anyone can help it would be greatly appreciated.
The default behavior of Entity Framework is it sets identity fields on entities from the database right after SaveChanges is called.
In the following sample code, before SaveChanges is called, my employee has a default ID of 0. After SaveChanges my employee has a generated ID of 1.
using (TestDbEntities context = new TestDbEntities())
{
Employee e = new Employee ();
e.FirstName = "John";
e.LastName = "Doe";
context.Employee.Add(e);
context.SaveChanges();
Console.WriteLine("Generated ID: {0}", e.ID);
Console.ReadKey();
}

how can i save the primary key of a entity in another entity when entity framework is saving

so I have this problem I am doing an import and I need when save the first table that primary key of the first table save too in another table that is not a foreing key , is a way that EF do that? Iam using EF5
is something like this, note that entity1.id is autoIncrement
foreach (var entity1 in Entities1)
{
DbContext.Entity1.Add(entity1);
var entity2 = new Entity2();
entity2.Entity1Id = entity1.id;
DbContext.Entity2.Add(entity2);
}
DbContext.SaveChanges();
Id is not generated until SaveChanges is called. So for this code to work, you have to rewrite it down like this:
DbContext.Entity1.Add(entity1);
DbContext.SaveChanges();
var entity2 = new Entity2();
entity2.Entity1Id = entity1.id;
DbContext.Entity2.Add(entity2);
DbContext.SaveChanges();

JPA and the last object added

I use EclipseLink JPA and for my work. And use GenerationType.TABLE.
When I create a new object using persist, how do I retrieve the id field of the created object.
Example:
em.getTransaction().begin();
Student student = new Student();
student.setName("Joe");
em.persist(student);
em.flush();
em.getTransaction().commit();
Query query = em.createQuery("SELECT e FROM Student e");
List<Student> list = (List<Student>) query.getResultList();
System.out.println(list);
em.close();
emf.close();
So I see all the students, but how do you know which one is the one that I created in an environment where there is competition.
Thanks in advance
I assume question is about generated id, because otherwise you of course already have id in your hands.
Generated id can be found after flush operation with following:
calling student.nameOfTheGetterForID
via PersistenceUnitUtil.getIdentifier:
//cast result to the type of id
em.getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(student);

Entity Framework Insert, Update, Delete During Same Transaction

I have a problem, I have a wizard that can update data AND insert data. So, if I have an existing list of team members, I can update their roles but If necessary, I can also add/insert a person to this team. So I can update roles and insert a new team member into the same table all during the same transaction. Data can be updated to and inserted to table teamMembers.
When I try to add a new teamMember, I also have an existing member where I simply want to update his role.
Both changes happen to the same table called TeamMember. When I debug the context, everything looks good. it shows that there are two changes that will occur for the TeamMember table. One transaction is the update and the other transaction is the insert. When I perform an update using:
var teamMember = new TeamMember
{
Name = user.FullName,
UserProfileId = user.UserProfileId,
RoleId = user.RoleId
};
TeamMemberList.Add(teamMember);
project.TeamMembers = TeamMemberList;
//And then call
this.Context.Projects.Attach(project);
this.Context.Entry(project).State = System.Data.EntityState.Modified;
it updates but the record that needs to be inserted fails.
HOW CAN I DO BOTH AN INSERT AND UPDATE TO THE SAME TABLE DURING THE SAME TRANSACTION?
CURRENT ERROR IS:
The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.
I think you need to add the TeamMember entity to the context's global list. Something like:
var teamMember = new TeamMember()
{
Name = user.FullName,
UserProfileId = user.UserProfileId,
RoleId = user.RoleId
}
project.TeamMembers.Add( teamMember );
this.Context.TeamMembers.Add( teamMember );
this.Context.SaveChanges();
How about loading the existing project entity first and then adding members.
var project = this.Context.Project.Where(p => p.ID = "bar").Include("TeamMembers").FirstOrDefault();
var teamMember= new TeamMember
{
Name = user.FullName,
UserProfileId = user.UserProfileId,
RoleId = user.RoleId
};
project.TeamMembers.Add(teamMember);
this.Context.SaveChanges()

How to create and store a (self-tracking) entity object on the server side?

I am trying to achieve the following using Entity framework 4.0 and self-tracking entities:
1) The client application request a book form the server by providing an ISBN number
2) The server performs a query on its database to see if the book is already present
3a) If the book is in the database, it returns it.
3b) If the book is not in the database, it will query Amazon for info, extract the required attributes, create a new book, store it in the database, and return it to the client
Now, 3b) is where the problems are... I can't find any information on how I can create an entity object (a book) on the server side, add it to the context and store it in the database. I have tried all sorts of things:
public class BookBrowserService : IBookBrowserService {
public Book GetBook(string ISBN) {
using (var ctx = new BookBrowserModelContainer()) {
Book book = ctx.Books.Where(b => b.ISBN == ISBN).SingleOrDefault();
if (book == null) {
book = new Book();
book.ISBN = ISBN; // This is the key
book.Title = "This title would be retrieved from Amazon";
Author author = new Author();
author.Name = "The author's name would be retrieved from Amazon";
book.Authors.Add(author);
ctx.Books.AddObject(book);
ctx.SaveChanges(); // This one always throws an exception...
}
return book;
}
}
}
Could anyone tell me what I am doing wrong?
It looks like the problem is related to the EDMX model.
I have a Book entity and an Author entity, with a many-to-many relationship.
The Book entity's Key is ISBN, which is a string of Max length 13.
StoreGeneratedPattern is set to None.
The Author entity's Key is Id, which is a Guid.
StoreGeneratedPattern is Identity.
The exception message is:
"Cannot insert the value NULL into column 'Id', table 'BookBrowser.dbo.Authors'; column does not allow nulls. INSERT fails. The statement has been terminated. "
But since StoreGeneratedPattern is set to Identity, shouldn't an Id value be created automatically?
Thanks,
Peter
It looks that the problem was that I used a Guid as Key in combination with StoreGeneratedPattern = Identity.
When I set StoreGeneratedPattern to None and create my own Guid using Id = Guid.NewGuid(), the problem is gone.
Apparently, the SQL server cannot generate Guids...
you can use StoreGeneratedPattern=Identity, but generated sql script based on your edmx doesn`t contain newid() in describing primary key(GUID). you can do this manually in generated sql script. 'BookId uniqueidentifier NOT NULL
DEFAULT newid()'. So id value will create GUID automatically.