Delete link table entry but not referenced table entries - entity-framework

I am using Entity Framework database-first model. I have 2 tables that are referenced by a link table.
For example:
When I update my edmx file from my database this creates the expected model:
Now what I want to do is delete an entry from the Product_User table without deleting the referenced entry in either of the related tables (Product or User).
I've tried both of these statements (together and separately) but neither seems to have any effect:
user.Products.Clear();
foreach (var product in products)
{
product.User = null;
}
Is what I'm trying to do possible with the model the way I have it now? And if so what am I doing wrong?
I noticed I can do what I'm trying to do if I add the link table explicitly to the model but I'm trying to avoid that.
Any help would be much appreciated. Thanks.

Your seconde way to go (with a loop) seems more like the correct way.
Instead of = null try to use the .Remove() function. I guess the remove function only remove the link between the two entity, not the entities related.
See this answer : Removing many to many entity Framework

Related

Update edmx after adding additional column to junction table

I'm using .Net 4.5, entity framework 5, database first. I have a junction (many-to-many) table in my database. For this example lets say the table is "StudentsCourses":
Students
-PkStudentId
-Name
Courses
-PkCourseId
-CourseNumber
StudentsCourses
-FkStudentId
-FkCourseId
This works just fine right now. The 'generate model from database' creates a Student entity with a navigation property to the Course entity. But here is where the trouble is:
I need to add another column to the StudentsCourses table. Lets just call this column "CourseYear". So our junction table would now look like this:
StudentsCourses
-FkStudentId
-FkCourseId
-CourseYear
So, I've added this column to the database and ran "Update Model from Database" on the edmx. I would expect to see an entity created for StudentCourses, with a navigation property to both Students and Courses. But no such entity is created. I still see the same two tables (Students & Courses) with the same navigation property as before.
I've done a lot of reading and researching, but haven't really come across a clear-cut answer. There is a wealth of information on code-first which I can't apply to my scenario. Is there a way to get what I'm after? Is it as simple as adding a PkId to the StudentCourses table? SQL Replication is preventing me from doing this. I would think the composite should suffice, but maybe EF needs a PK to do it's magic? I read a little bit about manually setting relationships, but could not find anything speaking to my particular situation. It could be that I am just missing a simple step in the process of updating the edmx from database. I've done this plenty of times when: adding new tables, adding columns, deleting columns, etc. I'm following the same steps as I always do, but maybe I need to do something different in this case?
Thanks ahead of time for any help. It is greatly appreciated. Please let me know if any more information would help.
From what I've gathered it appears as though EF will not generate a model for a table that doesn't have a Primary Key.
I'm a bit late for this, but you have the answer in this thread Updating Entity Framework Model after adding a field to a previous look up only table
As they say here, you have to delete the relationship between Students and Courses in the designer. Then update your model from the database, and make sure StudentsCourses table is checked in the Tables branch of the Add tab.

Entity Framework : map duplicate tables to single entity at runtime?

I have a legacy database with a particular table -- I will call it ItemTable -- that can have billions of rows of data. To overcome database restrictions, we have decided to split the table into "silos" whenever the number of rows reaches 100,000,000. So, ItemTable will exist, then a procedure will run in the middle of the night to check the number of rows. If numberOfRows is > 100,000,000 then silo1_ItemTable will be created. Any Items added to the database from now on will be added to silo1_ItemTable (until it grows to big, then silo2_ItemTable will exist...)
ItemTable and silo1_ItemTable can be mapped to the same Item entity because the table structures are identical, but I am not sure how to set this mapping up at runtime, or how to specify the table name for my queries. All inserts should be added to the latest siloX_ItemTable, and all Reads should be from a specified siloX_ItemTable.
I have a separate siloTracker table that will give me the table name to insert/read the data from, but I am not sure how I can use this with entity framework...
Thoughts?
You could try to use the Entity Inheritance to get this. So you have a base class which has all the fields mapped to ItemTable and then you have descendant classes that inherit from ItemTable entity and is mapped to the silo tables in the db. Every time you create a new silo you create a new entity mapped to that silo table.
[Table("ItemTable")]
public class Item
{
//All the fields in the table goes here
}
[Table("silo1_ItemTable")]
public class Silo1Item : Item
{
}
[Table("silo2_ItemTable")]
public class Silo2Item : Item
{
}
You can find more information on this here
Other option is to create a view that creates a union of all those table and map your entity to that view.
As mentioned in my comment, to solve this problem I am using the SQLQuery method that is exposed by DBSet. Since all my item tables have the exact same schema, I can use the SQLQuery to define my own query and I can pass in the name of the table to the query. Tested on my system and it is working well.
See this link for an explanation of running raw queries with entity framework:
EF raw query documentation
If anyone has a better way to solve my question, please leave a comment.
[UPDATE]
I agree that stored procedures are also a great option, but for some reason my management is very resistant to make any changes to our database. It is easier for me (and our customers) to put the sql in code and acknowledge the fact that there is raw sql. At least I can hide it from the other layers rather easily.
[/UPDATE]
Possible solution for this problem may be using context initialization with DbCompiledModel param:
var builder = new DbModelBuilder(DbModelBuilderVersion.V6_0);
builder.Configurations.Add(new EntityTypeConfiguration<EntityName>());
builder.Entity<EntityName>().ToTable("TableNameDefinedInRuntime");
var dynamicContext = new MyDbContext(builder.Build(context.Database.Connection).Compile());
For some reason in EF6 it fails on second table request, but mapping inside context looks correct on the moment of execution.

Entity Framework - adding the same entity twice in many-to-many relationships

Ok. So here is the deal. I have two entities - "Product" and "Parts". The product consists of parts. And parts are reusable in other products. The relation between those entities is many-to-many. And it all works great.
The problem is that I cannot add the same part to the same product twice. EF seems to force all the related entities to be unique. Consider the following code:
var product = context.Create<Product>();
var part = GetSomePart();
Console.WriteLine(product.Parts.Count); // will output 0
// Add a part
product.Parts.Add(part);
Console.WriteLine(product.Parts.Count); // will output 1
// Add the same part again
product.Parts.Add(part);
Console.WriteLine(product.Parts.Count); // will output 1!
So ok, I get the point - avoid duplicates or something. But I need this to be possible. Is there a way to do this (to tell EF to stop enforcing unique values) without creating an additional table? Or is the only way to resolve this is to manually add the intermediate table and handle the many-to-many myself?
In this case you will have to create another table called "ProductParts" which will have an identity unique key, and which can hold references to both product and part, and they can be multiple too.
In the second add statement it will not add another object because part is already in added state. So you need to create a new object with same properties add it again.
product.Parts.Add(new Part{someProperty=part.someProperty ... ect });
if you want to reduce code you can use Automapper ( http://automapper.codeplex.com/ )to copy all properties,
product.Parts.Add(Mapper.Map<Part,Part>(part));

Entity Framework query: access foreign key (navigation) data from record

I'm new to EF and I have two tables, the first called ContestEntry and the second Items which has a one to many relationship with ContestEntry. I'm trying to access Contest Entries and then from there get the related Item information. Here is the code I'm using.
ContestEntry cEntry =
Ctx.ContestEntries.Include("Item").Where(ce => ce.ID == 4).First();
The problem is that the Item relationship is NULL when I look at it in the debugger.
I'm probably missing something just not sure. Any help would be appreciated.
Thank You!
In your question, you mention the seconds table is "Items", yet in your LINQ query, you're including "Item" - just a typo??
Also, another way to load a referenced entity would be this:
ContestEntry cEntry =
Ctx.ContestEntries.Include("Item").Where(ce => ce.ID == 4).First();
if(!cEntry.Items.IsLoaded)
{
cEntry.Items.Load();
}
If you have a 1:n navigational property, you should be able to check whether it's been loaded, and if not, load it on demand when you need it.
Marc

Entity framework - "Problem in mapping fragments"-error. Help me understand the explanations of this error

Error 3007: Problem in Mapping Fragments starting at lines 186, 205: Non-Primary-Key column(s) [WheelID] 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.
I found several places on the web describing this error, but I simply don't understand them. (confused smiley goes here)
One
Two
Three
Four
There is something pretty fundamental here, I must be missing. Can you explain it, so that I understand it? Maybe using my real life example below?
Foreign key 1:N Wheels.Id -> Slices.WheelId
I add them to entity framework, and WheelId is not visible in the Slices-entity.
Doing some workaround (deleting the relationship from the db before adding tables to EF - then re-creating it and updating EF) I managed to get the WheelId to stay in Slices, but then I get the error mentioned at the top.
Since Slices.WheelId is an FK, you cannot expose it in your client model, period. There are ways to get the value, though.
var wheelId = someSlice.Wheels.ID;
Update In EF 4 you can do this by using FK Associations instead of independent associations.
Try to remove foreign property column from Entity set using entity model design it will solve your problem
For example
We have two tables one is customer and other one is order, using entity model design we added association between customers and orders when we do this Ado.net entity framework i will add navigation properties to both below tables.
Like
Customer.Orders - Here order is list
Order.Customer
One - Many relation.
So we need to remove property from with name CustomerId[Foreign key column] from Order entity set.
For reference:
http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/2823634f-9dd1-4547-93b5-17bb8a882ac2/
I was able to overcome this problem by the following steps:
right click the designer window
Select 'update model from database'
Select Add AND make sure that the 'Include foreign key columns in the model' checkbox is selected.
click on Finish...
I had set foreign keys up in the database but framework still wasn't pulling them in correctly. So I tried to add the association myself. 
However, when I did this I would get a mapping error. It took me A WHILE but I figured out. What I did was set up the association using the entity toolbox association tool and then you have to double click on the association (1 to many) line and set the primary and foreign key there. Hopefully, this to help others who might have the same problem. I couldn't find the answer anywhere.
I had this problem for quite a different reason, and the message was slightly different; it didn't say "data inconsistency is possible because the corresponding conceptual side properties can be independently modified."
I have a table involved in my model with a binary column where I store image data. I only want this data returned when I need it (performance is a feature), so I split the table using a method similar to this. Later on, I added a property to that table, then updated the model from the database. The wizard added the property to both entity types that refer to the table with the added property. I had to delete it from one of them to solve the error.
I've had this happen because Entity Framework Update wizard mismapped some keys (or did not update?). As a result, some columns were mistakenly labeled as keys, while actual key columns were treated as plain columns.
The solution was to manually open EDMX file, find the entities, and update the keys.
Couldn't get any of the answer to work with EF6. The problem seems to be the framework doesn't import the foreign keys correctly as Associations. My solution was removing foreign keys from the tables, and then manually adding the associations using Entity Framework model, using the following steps: Entity Framework - Add Navigation Property Manually
For LinQ to Entities queries in EF1, my workaround for not having access to the foreign key as a property is with the following code, which does not produce a join query to the associated table:
dbContext.Table1s.FirstOrDefault(c => (int?)c.Table2.Id == null)
i.e, the generated SQL is:
...WHERE ([Extent1].[Table2Id] IS NULL)...
Solution is to allow deleting Rule = Cascade on Sql association.
Same thing as to be done on .edmx model, adding element to
association:
<Association Name="FK_Wheels_Slices">
<End Role="Wheels" Type= "your tipe here" Multiplicity="1">
<OnDelete Action="Cascade" />
</End>
</Association>
I had a table already mapped in EF. I added two more tables which had foreign keys in the previously added table. I then got the 3007 error.
To fix the error I deleted all three tables from the EDMX file, and then re-added them all at once together (via "Update Model from Database..."), instead of in stages.
I checked my Error List window and noticed I had errors in the model. Fixed them and all is well
in my case I solved this error by tick (include foreign key columns in the model)
- update Model from database
- tick (include foreign key columns in the model)
- finish