Saving many-to-many relationship objects in entity framework - c#

I'm trying to save an entity that forms part of a many-to-many relationship in the entity framework and am getting the error: Unable to update the EntitySet 'zRM_OP_defaultloccvgsMapping' because it has a DefiningQuery and no element exists in the element to support the current operation.
My google-fu is weak on this one, but I understand I may have to edit the designer code and hook up a stored procedure to manually do the insert.
My table structure looks like this:
locations:
LOCID,
blah..
coverages:
CVGID,
blah..
loccvgs:
LOCID,
CVGID (no keys)
Help!

I have this exact question, but I've come up with a solution. I'll warn you though, it's a really bad one. In my situation I have 3 tables:
Video
- VideoId , int , PK
- blah
Comment
- CommentId, int, PK
- UserId, int (user that made the comment)
- CommentText, string
VideoComments
- VideoId, int, PK
- CommentId, int, PK
First of all, for entity framework to setup the relationship correctly both columns on the association table (VideoComments in my case) must be a primary key.
That said, here is how I am adding a new comment.
public VideoDTO AddCommentToVideo(VideoDTO pVideo, CommentDTO pComment)
{
Video video = context.Videos.Where(v => v.VideoId ==
pVideo.VideoId).FirstOrDefault();
User user = context.Users.Where(u => u.UserId ==
pComment.User.UserId).FirstOrDefault();
Comment comment = new Comment();
comment.CommentText = pComment.CommentText;
comment.User = user;
comment.Videos.Add(video);
context.AddToComments(comment);
context.SaveChanges();
return pVideo;
}
This is very bad...like crossing the streams bad. I do 2 queries to get the full objects mandated by Entity Framework so I can create a new comment. I would like a better way to do this, but I don't know one. Maybe this can help.

Related

Multiple foreign keys pointing to same table in Entity Framework are indistinguisible

I'm unable to distinguish between foreign keys when two or more point to the same table through the database context.
For example, if I have a db with two tables, Users and Invoices.
Users has two fields: userId and userName
Invoices has three fields: invoiceNumber, cashierUserId, supervisorUserId
cashierUserId and supervisorUserId are foreign keys pointing to userId in the Users table.
Now in entity framework via the db context when I try to get the cashier or supervisor's user name I can't tell which user name I'm going to get.
dbContext.Invoices.Single(i => i.invoiceNumber == 1).Users.userName;
Which user name do I get? The cashier's or the supervisor's? How do I tell it which one I want?
First off, your code has an issue. The "Users" collection wouldn't have a property called "userName". It should probably read:
dbContext.Invoices.Single(i => i.invoiceNumber == 1).Users.First().userName;
Obviously, .First() is not going to help with the "distinguishing" problem. For that, I see two solutions:
Modify your context so each navigation property has a special name ("Cashier", "Supervisor"). Then you would just write:
dbContext.Invoices.Single(i => i.invoiceNumber == 1).Cashier.userName;
Give your user a "type" field. This could be a string stored in the user table, or likely a foreign key into a "UserTypes" table (in a normalized database). Then your query becomes:
dbContext.Invoices.Single(i => i.invoiceNumber == 1).Users.First(u => u.UserType == "Cashier").userName;
Using a different table would change the predicate a bit, but you get the idea. To help guide your design, remember that EF isn't very different than standard SQL. How would you craft a standard SQL query to distinguish the two? You would base it on foreign key (the first option), or another field on the users table (the second option).

Entity framework get the foreign key

I have 1:n relationship between to tables in a database: Employee (1) : Role (n)
Role has foreignKey named idEmployee
I want to create a linq statement which will get every role for a given customer. I want to make something like this:
var myQuery = from r in Role
where r.idEmployee == someId
select r;
But, r doesn't have an idEmployee property! How can I get the value of the foreign key?
If you're using EF 4.0 (.NET 4.0), and a database-first programming model with an EDMX model (visual designer), then you need to make sure to have the option Include foreign key columns in the model checked when you add tables to your EDMX model:
If you don't have this option checked, then EF 4.0 will behave the same as EF 1.0/3.5 (in .NET 3.5) which is to include a navigation property - but not the foreign key column as a separate column.
If you are using EF4.0 at least, this will give you what you need: Foreign keys in Entity Framework
If you're using EF1.0, your problem is more serious since it does not show foreign keys in model. You need to iterate through EntityKey.EntityKeyValues collection in search of valid value. But I think this would only get you value of foreign key and would not work in query (since EF would not know how to translate it to SQL query).
But since you have foreign keys, why don't you simply use NavigationProperty to navigate to Employee entity and check value there?
var myQuery = from r in Role
where r.Employee.idEmployee == someId
select r;
Use the include method on Employee class to bring back all the related roles:
var myQuery = from e in Employees.Include(emp => emp.Roles)
where e.EmployeeId == someId
select e

Table-per-type inheritance insert problem

I followed this article on making a table-per-type inheritance model for my entities, but I ran into some issues. Below I'm posting steps to reproduce the problem I'm having in a minimal environment to rule out other factors.
First, I created a new MS SQL Server 2008 R2 database with the following two tables:
Users
Id : bigint (PK and set it as the identity column)
Name : nvarchar(25) NOT NULL (whatever, some random property
Customers
Id : bigint (PK, identity column, and FK on Users.Id)
Title : nvarchar(25) NOT NULL (also whatever, some random property)
Next, I generated the .edmx entity model from the database, and followed the link at the top verbatim. That is to say, I deleted the association between User and Customer, set User as the base class of Customer, deleted the Id property from the Customer entity, and made sure that the Customer.Id column was mapped to the inherited User.Id property. I then ran the following small program:
using (var db = new EF_Test.testEntities())
{
var cust = db.Users.CreateObject<Customer>();
db.Users.AddObject(cust);
db.SaveChanges();
}
I get the following error when I make that last call:
"A value shared across entities or associations is generated in more than one location. Check that mapping does not split an EntityKey to multiple store-generated columns."
With the following inner exception:
"An item with the same key has already been added."
Any ideas on what I could be missing?
A quick google on the error message turned up the following solution, maybe it helps you:
http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/4bfee3fd-4124-4c1d-811d-1a5419f495d4
I think that I figured it out. The
table for the Party sub type had its
key column set to autogenerate a key
value and since it's derived, the EF
wanted to set that value explicitly.
So have you tried removing the "identity" setting from the customer table? So it doesn't autogenerate the primary key?
Hope this helps.
I finally found the source of my troubles. For those still interested, in the Customers table, the Id column should not have been set to the identity column of the table (PK and the FK dependency are fine though).
Why you don't want to make a foreign key (UserId) as a separate column? Maybe it can help you.
Also try to use model first approach and generate db after model creation as it is described in the following article.

Defining a 1 to many relationship in Entity Framework

I'm trying to create a 1:m relationship using Entity Framework (.net 4.0) and am getting the following error:
App_Code.Model.msl(36,6) : error 3007: Problem in mapping fragments
starting at lines 6, 36:Column(s) [ProductId] are being mapped in
both fragments to different conceptual side properties.
What i have is a Products table, and a Features table. The idea is that Products have many Features. Products each have a ProductId, and the Features have a ProductId foreign key.
Now the catch is that the foreign key doesn't exist in sql server, and i don't want it to. If it did, then it all automagically works nicely.
In the EDMX designer, i created an association from the product to the feature entity, then edited the mapping details of the ProductFeature association to be based on the Features table, which i think would make it work.
Any ideas? Thanks very much.
This is a M x N relationship. Why? Because a feature can be assigned to more than one type of product.
You should have a table ProductFeatures like so:
ProductId FeatureId
1 1
1 2
2 1
2 2
Found one solution: delete the scalar property 'ProductId' from the feature entity:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/a71901fb-97ec-4072-949a-c0c66a9775b1
However, in the auto-generated relationships that EF gives you if you set up the foreign key in the database, the eg 'ParentId' fields are present in the child as a scalar field.
So i'm a little confused still.
-edit- Further help:
http://www.hanselman.com/blog/CreatingAnODataAPIForStackOverflowIncludingXMLAndJSONIn30Minutes.aspx

Entity Framework model and foreign key property

I have 2 tables that I import to EF model.
First table has a property [section] that acts as foreign key to the second table.
When I map this property in model to the table and try to compile I get this error:
Problem in Mapping Fragments starting
at lines 158, 174: Non-Primary-Key
column(s) [Section] are being mapped
in both fragments to different
conceptual side properties - data
inconsistency is possible because the
corresponding conceptual side
properties can be independently
modified.
If i remove this property from the model it passes, but when I query the data I don't have the section field.
I know that I can get it by using the navigation field and reading this property from the second table, but to make it work I must include the other table in my query.
var res = from name in Context.Table1.Include("Table2")...
Why do I need to include the association just for one field?
UPDATE
To make it more clear:
Table 1 has fields:
ItemId - key
section - foreign key
title
Table 2 has fields:
SectionId - key
Name
When I set the associations the section property from the first table must be removed.
What are your Primary Keys and is one Store Generated? I suspect you are missing a PK or an Identity somewhere.
Tip: One alternative when having mapping problems is to create the model you want in the EDMX designer and then ask it to create the database for you. Compare what it creates to what you have made in SQL and it's often easy to spot the mistakes.
In EF 4 you can use FK associations for this.
In EF 1 the easiest way to get one field from a related table is to project:
var q = from t1 in Context.Table1
where //...
select new
{
T1 = t1,
Section = t1.Section.SectionId
};
var section = q.First().Section;
If it's a key property, you can get the value via the EntityKey:
var t1 = GetT1();
var section = (int)t1.SectionReference.EntityKey.Values[0].Value;
Generally, I don't like this last method. It's too EF-specific, and fails if your query MergeOption is set to NoTracking.

Categories