Merge Key constraint with Entityframework - entity-framework-core

I am a .NEt student trying to build a simple pizza webbshop. I am using Entityframework to build the database. The errormessage I get is this:
The MERGE statement conflicted with the FOREIGN KEY constraint "FK_Products_Categories_CategoryID". The conflict occurred in database "TomasosPizzeria", table "dbo.Categories", column 'CategoryID'.
The statement has been terminated.
I have googled and tried to solve this pne alone by renaming the properties back and forth. Here are my classes:
public class Product
{
public int ID { get; set; }
public string ProductName { get; set; }
public int ProductPrice { get; set; }
public string Ingridients { get; set; }
//--
public List<OrderDetail> OrderDetails { get; set; }
[ForeignKey("Categories")]
public int CategoryID { get; set; }
public virtual Category Categories { get; set; }
}
public class Category
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
List<Product> Products { get; set; }
}
I am using a DbInitializer to set som test values. I have had problems giving the product object a category with the corresponding value.
var categories = new Category[]
{
new Category{CategoryName="Pizza"},
new Category{CategoryName="Pasta"},
new Category{CategoryName="Sallad"},
};
var products = new Product[]
{
new Product{ProductName="Äcklig Calzone", Ingridients="Gamla tomater, möglig ost, trötta oliver, Unken skinka", ProductPrice=150},
new Product{ProductName="Italiensk skit", Ingridients="Proscutti, halvfärdig mozzarella, trötta oliver, skämd vattnig proscutti", ProductPrice=250},
new Product{ProductName="La bussola", Ingridients="Äckliga tomater, giftiga räkor, levande musslor, rutten skinka",CategoryID = 2,<--Here-- ProductPrice = 105 }
};
foreach (Product s in products)
{
context.Products.Add(s);
}
context.SaveChanges();
I am thankful for all the help I get. Please tell me if you wish to see any more of my code.

Solved it by giving CategoryID to the two other products.

Related

update foreign key using entity framework

i am trying to update foreign key in a table named(Friendship).The foreign key is of the table named(FriendshipStatus) the problem is that all the values are updated except the foreign key. I m using code first approach.
Friendship Class
public class Friendship
{
public int Id { get; set; }
public User UserOne { get; set; }
public User UserTwo { get; set; }
public FriendshipStatus Status { get; set; }
public User ReqSB { get; set; }
public RelationType RelationType { get; set; }
public Relationship Relationship { get; set; }
public DateTime FriendshipDate { get; set; }
}
FriendshipStatus class
public class FriendshipStatus
{
public int Id { get; set; }
public string Name { get; set; }
}
Here is the code for update
using (context)
{
Friendship f = getFrienshipRecord(u1, u2); // get single record from db which is to be updated
if (f != null)
{
Friendship ff = new Friendship();
ff.Status = new FriendshipStatus() { Id = 2}; //actually wants to update this this field
ff.Id = f.Id;
ff.FriendshipDate = DateTime.Now;
context.Entry(ff).State = EntityState.Modified;
context.SaveChanges();
}
}
The above code changes datetime but it does not change foreign key.
This is the technique I use for updates that include a child. First, I like to expose the Foreign Key as part of the parent. If you name it FriendshipStatusId, EF will make the association automatically or you can add an annotation or fluent code if preferred:
public class Friendship
{
public int Id { get; set; }
public User UserOne { get; set; }
public User UserTwo { get; set; }
public int? FriendshipStatusId { get; set; } // optional FK
public FriendshipStatus Status { get; set; }
public User ReqSB { get; set; }
public RelationType RelationType { get; set; }
public Relationship Relationship { get; set; }
public DateTime FriendshipDate { get; set; }
}
Now you can do your update by simply fetching the entity (which puts it under tracking) and updating the FK:
using (context)
{
Friendship f = getFrienshipRecord(u1, u2); // get single record from db which is to be updated
if (f != null)
{
f.FriendshipDate = DateTime.Now;
f.FriendshipStatusId = 2;
context.SaveChanges();
}
}
Note that if you add the FK you may need to do a migration or regenerate your database because the EF default might be something like FriendshipStatus_Id.

Updating a relation between two Entity Framework entities?

I have two related Entity Framework 6 classes in my data layer.
public class Order
{
public int Id { get; set; }
public virtual SalesStatus SalesStatus { get; set; }
}
public class SalesStatus
{
public SalesStatus()
{
Orders = new List<Order>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual List<Order> Orders { get; set; }
}
public class OrderVM
{
public int Id { get; set; }
public SalesStatus SalesStatus { get; set; }
}
I am using Automapper to map these to my view models and back again.
cfg.CreateMap<Order, OrderVM>()
.MaxDepth(4)
.ReverseMap();
The status entity is used to populate a drop down list.
In my method I am taking the selected value and trying to update the order record to the new selected status.
private bool SaveOrderToDb(OrderVM orderVM)
{
using (var db = new MyContext())
{
var order = AutomapperConfig.MapperConfiguration.CreateMapper().Map<OrderVM, Order>(orderVM);
order.SalesStatus = db.SalesStatuses.Find(Convert.ToInt16(orderVM.SalesStatusSelectedValue));
db.Set<Order>().AddOrUpdate(order);
db.SaveChanges();
}
return true;
}
This does not update the relationship in the database. Why? What am I missing?

If Exists Dont Add Data Entity Framework Many-To-Many

I have these two Models the logic is here One Post can have multiple Categories.
public class Post
{
public Post()
{
this.Categories = new HashSet<Category>();
}
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ShortDescription { get; set; }
public string PostImage { get; set; }
public string Thumbnail { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? PublishedDate { get; set; }
public string CreatedBy { get; set; }
public virtual ICollection<Category> Categories { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
I have three static categories.
When I am trying to add new post its multiplexing CategoryTable creating new categories with same name ,And Mapping Them in to CategoryPostsTable.
The problem is here i want to map that data with existing categories. I dont want to add new category with same name.
I am using Repository Pattern how should i control that ? Is EF has some solution for that ?
I assume you have code like:
var post = new Post();
post.Categories.Add(cat);
context.Posts.Add(post);
...where cat is a Category object representing an existing category.
The latter Add method (DbSet.Add) doesn't only mark the received entity as Added but all entities in its object graph that are not attached to the context. So cat will also be marked as Added if it wasn't attached yet.
What you can do is
context.Entry(cat).State = System.Data.Entity.EntityState.Unchanged;
Now EF will only create the association to the category, but not insert a new category.

SQLite-Net Extensions: How to get rid of relationship records?

Let's say I have a many-to-many relationship like in the official sample:
public class Student
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
[ManyToMany(typeof(StudentSubject))]
public List<Student> Students { get; set; }
}
public class Subject
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Description { get; set; }
[ManyToMany(typeof(StudentSubject))]
public List<Subject> Subjects { get; set; }
}
public class StudentSubject
{
[ForeignKey(typeof(Student))]
public int StudentId { get; set; }
[ForeignKey(typeof(Subject))]
public int SubjectId { get; set; }
}
If I am now deleting a Student, the relationship record represented by the intermediate object does not get deleted, too. (And if I am enabling cascading deletion, the Subject gets deleted – what should not happen.)
Currently I am cleaning up manually by deleting the record with a custom query, but is there a better way with sqlite-net?
You can set to null or an empty list the Subjects property and call UpdateWithChildren on the student object.
student.Subjects = null;
conn.UpdateWithChildren(student);
It will update the student object and its relationships, deleting all the records for that student, which is equivalent to:
conn.Execute("DELETE FROM StudentSubject WHERE StudentId = ?", studentId);
The drawback is that you have one more 'update' statement executing in the database if you let SQLite-Net Extensions handle the relationship.

Entity Framework and 2 associations on the same table. Is it possible?

I have 3 tables:
Product
Category
ProductCategory
when doing entity framework Database First it creates 2 classes.
Product {
int ProductId
virtual ICollection<Category>
}
Categories {
int CategoryId
virtual ICollection<Product>
}
this is great.
I want to create a new property on the table ProductCategory, for example, CreateDate
So I will have one more entity (ProductCategory) with the CreateDate property :
Product
Category
ProductCategory
So far so good, but it removes the navegability from Product to Category and creates the navegability from Product to ProductCategory and then to Category.
I manually changed in model browser and added a new navegability that create the previous behaviour in classes so I ended up with what I want :
Product {
int ProductId
virtual ICollection<Category>
ProductCategory
}
Category {
int CategoryId
virtual ICollection<Product>
ProductCategory
}
ProductCageory {
Product
Category
}
all compiles fine, but when I run the code and update an entity the following error raises :
error 3034: Problem in mapping fragments starting at lines 2445, 2452:
Two entities with possibly different keys are mapped to the same row.
Ensure these two mapping fragments map both ends of the AssociationSet
to the corresponding columns.
Is there any way to keep my desired scenario (Both navegabilities from Product to ProductCategory and to Category and vice versa) ? If so, how can I get rid of this error ? am I missing mapping something ?
Tryied to be the less verbose possible but I don't mind adding more information or updating the question if anything missing so don't hesitate to ask for more info. Thanks.
Extra: Using MySql 6.8.3 with Entity Framework 6 (latest minus version) Database First using DbContext and T4.
updated:
This is what I want to have :
public class Product
{
public int Id { get; set; }
public ICollection<ProductCategory> ProductCategories { get; set; }
public ICollection<Category> Categories { get; set; }
}
public class Category
{
public int Id { get; set; }
public ICollection<ProductCategory> ProductCategories { get; set; }
public ICollection<Product> Products { get; set; }
}
public class ProductCategory
{
public int Id { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
If you want to have many to many relationship that can navigate both ways, you should have as follow.
public class Product
{
public int Id { get; set; }
public ICollection<ProductCategory> ProductCategories { get; set; }
[NotMapped]
public ICollection<Category> Categories
{
get { return (ProductCategories ?? new ProductCategory[0]).Select(pc => pc.Category).ToArray(); }
}
}
public class Category
{
public int Id { get; set; }
public ICollection<ProductCategory> ProductCategories { get; set; }
[NotMapped]
public ICollection<Product> Products
{
get { return (ProductCategories ?? new ProductCategory[0]).Select(pc => pc.Product).ToArray(); }
}
}
public class ProductCategory
{
public int Id { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}