I am creating a Web API model for banking system each branch have a managerId which is a foreign key to the users table.
When I want to post a new branch, I have to fill all the columns for branch and the manager. How can I only insert branch columns?
Branches entity:
public class Branch
{
public int Id { get; set; }
public string BranchName { get; set; }
public string? PhoneNumber { get; set; }
public User BranchManager { get; set; }
public ICollection<Device> Devices { get; set; }
}
Users entity:
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Address { get; set; }
public int ? SuperviseID { get; set; }
public UserTypes UserType { get; set; }
[ForeignKey("SuperviseID")]
public User? Supervise { get; set; }
public ICollection<Branch>? Branches { get; set; }
}
My code:
public void PostBranch(Branch branch)
{
var db = new OrganizationDbContext();
db.Add(branch);
db.SaveChanges();
}
Post request body:
{
"id": 5,
"branchName": "Bank",
"phoneNumber": "9999999",
"branchManagerId": 7
}
When I left other columns empty, I get an error:
SqlException: Cannot insert the value NULL into column
I find where the problem is:
public void PostBranch(Branch branch)
{
var db = new OrganizationDbContext();
db.Add(branch);
db.SaveChanges();
}
db.Add(branch) should convert to db.Branches.Add(branch)
Related
I have this models
public class Food
{
public int FoodId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Ingredients { get; set; }
public string PhotoPath { get; set; }
public ICollection<Menu> Menus { get; set; }
}
public class Menu
{
public int MenuId { get; set; }
[Column(TypeName = "date")]
public DateTime MenuDate { get; set; }
public bool IsPublished { get; set; }
public ICollection<Food> Foods { get; set; }
}
and added this in model builder
modelBuilder.Entity<Food>()
.HasMany(left => left.Menus)
.WithMany(right => right.Foods)
.UsingEntity(join => join.ToTable("menu_foods"));
this will create a table menu_foods that has food_id and menu_id
My question is, how can I insert the data for that table to link my menu to food?
current code that I have to insert:
var food = dbContext.Foods.First();
var menu = new Menu {
... // any data I set
}
menu.Foods.Add(food);
The code above throws PK error as it tries to insert new instance of food instead. My goal here is to create data on the linking table instead.
I'm using EF code first migrations in MVC5 with SQL Server.
I created a post method, I'm posting DTO data from the client and its all fine i believe, but when i try to save the data to the db i get this invalid column name exception on a foreign key property.
This is the first time i actually counter this error. I checked other questions and most answers were related to the [ForeignKey] data annotation but i think i implemented it the right way
This is the Model
public class ServiceProvider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public double YearsOfExperiance { get; set; }
public double AverageRank { get; set; }
public string Nationality { get; set; }
public ICollection<JobImage> JobImages { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<Rank> Ranks { get; set; }
public bool Active { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public Category Category { get; set; }
public bool Approved { get; set; }
}
This is the controller ActionResult method
[HttpPost]
public ActionResult AddServiceProvider(ServiceProviderDTO serviceProvider)
{
bool isInDb = _context.ServiceProviders.Any(s => s.Name == serviceProvider.Name) ? true : false;
//var serviceProviderInDb = _context.ServiceProviders.Where(s => s.Name == serviceProvider.Name).FirstOrDefault();
var newServiceProvider = new ServiceProvider();
if (isInDb == false)
{
newServiceProvider = new ServiceProvider
{
Id = Guid.NewGuid(),
Name = serviceProvider.Name,
PhoneNumber = serviceProvider.PhoneNumber,
YearsOfExperiance = serviceProvider.YearsOfExperiance,
Nationality = serviceProvider.Nationality,
CategoryId = serviceProvider.CategoryId,
Active = true,
Approved = serviceProvider.Approved == null ? false : serviceProvider.Approved.Value
};
_context.ServiceProviders.Add(newServiceProvider);
_context.SaveChanges();
}
return RedirectToAction("Index", "Home");
}
The error occurs on _context.SaveChanges();
It states that CategoryId is an invalid column name
This is not the first time that i use code first migrations and i never came across this error before so i really have no idea why this happens!
I would have the model like this.
The ForeignKey attribute belong to the Category property
public class ServiceProvider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public double YearsOfExperiance { get; set; }
public double AverageRank { get; set; }
public string Nationality { get; set; }
public ICollection<JobImage> JobImages { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<Rank> Ranks { get; set; }
public bool Active { get; set; }
public int CategoryId { get; set; }
[ForeignKey("CategoryId")]
public Category Category { get; set; }
public bool Approved { get; set; }
}
you need delete this property public int CategoryId { get; set; }
your property public Category Category { get; set; } is the ForeignKey and add the DataAnnotations [ForeignKey("CategoryId")]
it would look like this
public class ServiceProvider
{
public Guid Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public double YearsOfExperiance { get; set; }
public double AverageRank { get; set; }
public string Nationality { get; set; }
public ICollection<JobImage> JobImages { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<Rank> Ranks { get; set; }
public bool Active { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public Category Category { get; set; }
public bool Approved { get; set; }
}
Hi every one I want to save complex data using Entity Framework and C#. I have 2 classes Product and Order defined as follows
Product Class
public class Product
{
[Key]
public int Id { get; set; }
public string SKU_Code { get; set; }
public string Product_Name { get; set; }
public string Quantity { get; set; }
public string Price { get; set; }
public string Image { get; set; }
public DateTime Created_Date { get; set; }
public DateTime Modified_Date { get; set; }
}
Order Class
public class Order
{
[Key]
public long ID { get; set; }
public string Order_Id { get; set; }
public string Payment_Type { get; set; }
public string Customer_Name { get; set; }
public string Shipping_Address { get; set; }
public DateTime Order_Date { get; set; }
public DateTime Modified_Date { get; set; }
public bool Flag { get; set; }
public List<Product> ProductDetails { get; set; }
}
And I want to save data Order details and my piece of code is as follows.
public Order Add(Order odrerDetails)
{
using (var context = new EcommerceDBContext())
{
var MyOrder_Id = Helper.Random(7); //Generate random orderID from my class
foreach (var detail in odrerDetails.ProductDetails)
{
odrerDetails.Order_Id = MyOrder_Id;
odrerDetails.Quantity = Convert.ToInt32(detail.Quantity);
odrerDetails.Amount = Convert.ToDouble(detail.Price);
//Other Details
context.objOrderListing.Add(odrerDetails);
}
context.SaveChanges();
return odrerDetails;
}
}
This gives me perfect data but when it comes to context.SaveChanges(); it return's me error.
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types.
To me you domain model seems all wrong. The order should just be used for grouping, its a typical e-commerce scenario.
When you get a receipt of your purchases, you get one receipt with every Item and price listed next to it. Its considered as one order of multiple things, not multiple orders of multiple things.
Reading your last comment, you cant have multiple orders with the same order id. Try to understand the domain first before trying to solve it with code. Also,you have no notion of a Customer with an Order.
public class Product
{
[Key]
public int Id { get; set; }
public string SKU_Code { get; set; }
public string Product_Name { get; set; }
public string Price { get; set; }
public string Image { get; set; }
public DateTime Created_Date { get; set; }
public DateTime Modified_Date { get; set; }
}
public class Order
{
[Key]
public long ID { get; set; }
public string Order_Id { get; set; }
public string Payment_Type { get; set; }
public string Customer_Name { get; set; }
public string Shipping_Address { get; set; }
public DateTime Order_Date { get; set; }
public DateTime Modified_Date { get; set; }
public bool Flag { get; set; }
public List<OrderLineItem> Items { get; set; }
}
public class OrderLineItem
{
[Key]
public long ID { get; set; }
public long Order_Id { get; set; }
public long Product_Id {get; set;}
public int Quantity {get; set;}
}
//EDMX File
http://pastebin.com/btTCRMf7
I have 2 tables Customers and Sites
//Site
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int CustomerID { get; set; }
public int CityID { get; set; }
public int CountryID { get; set; }
public int EncodedBy { get; set; }
public System.DateTime DateEncoded { get; set; }
public virtual City City { get; set; }
public virtual Country Country { get; set; }
public virtual ICollection<Invoice> Invoices { get; set; }
public virtual User User { get; set; }
public virtual Customer Customer { get; set; }
//Customer
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int CityID { get; set; }
public int CountryID { get; set; }
public int CreditTermID { get; set; }
public int EncodedBy { get; set; }
public System.DateTime DateEncoded { get; set; }
public virtual City City { get; set; }
public virtual Country Country { get; set; }
public virtual CreditTerm CreditTerm { get; set; }
public virtual User User { get; set; }
public virtual ICollection<Invoice> Invoices { get; set; }
public virtual ICollection<Site> Sites { get; set; }
//Country
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
public virtual ICollection<Site> Sites { get; set; }
//City
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
public virtual ICollection<Site> Sites { get; set; }
//SiteModel
private static IQueryable<Site> Build(this DbSet<Site> query)
{
return query.Include("User").Include("City").Include("Country").Include("Customer");
}
public static Site Find(int siteID)
{
using (DragonRentalsEntities context = new DragonRentalsEntities(new ConfigurationManager().ConnectionString))
{
Site result = context.Sites.Build().SingleOrDefault(s => s.ID == siteID);
return result;
}
}
public static Site Update(Site _updatedSite)
{
using (DragonRentalsEntities context = new DragonRentalsEntities(new ConfigurationManager().ConnectionString))
{
context.Sites.Attach(_updatedSite);
context.Entry(_updatedSite).State = EntityState.Modified;
context.SaveChanges();
return Find(_updatedSite.ID);
}
}
Site test = SiteModel.Find(1);
test.City = null;
test.CityID = 1;
test.Country = null;
test.CountryID = 1;
test.Customer = null;
test.CustomerID = 1;
SiteModel.Update(test);
i am getting 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.
however, adding test.Customer.City = null; before updating the object would work. it seems like Customer.City and Site.City is conflicting. can somebody explain why? or any workaround?
I can explain why. Include persists entity to load all the include objects.So our site object has all references to your clusses (City, Country,User Customer). I think that is the problem. The solve can be to load only site object:
Site result = context.Sites.SingleOrDefault(s => s.ID == siteID);
so it would load only ids of the site object. Than you can load refered objects by it ids in runtime where you need.
I think it is because when you use include, you operate objects and collections of objects dbContext tracks this changes and saves them when you call
context.SaveChanges();
a bit refactored code btw:
public static Site Update(Site _updatedSite)
{
using (DragonRentalsEntities context = new DragonRentalsEntities(new ConfigurationManager().ConnectionString))
{
if (context.Entry(_updatedSite).State == EntityState.Detached)
context.Entry(_updatedSite).State = EntityState.Modified;// attaches entity and marks it as modified if it is detached
context.SaveChanges();
return _updatedSite; //after save changes u have the same object as u send in your Update function
}
}
Comment answer
Slauma if i don't set it to null, i won't be able to attach them in the update method, the same error would be triggered
Answer:
Because when you include all entities you have got already attached to your context objects.
Btw Include transforms on sql inner join statement so may be your snapshot of db objects doesnt contain City with that ID.
I'm using asp.net mvc 3 and EF 4.1 with visual studio 2010 and im new to it.
i have a problem about last inserted id. i have two table in my db "points_Order" and "points_OrderDetails".
db.Order.Add(po);
db.SaveChanges();
//second thing i have tried
var orderID = (from oi in db.Order
select oi.ID)
.Max(i => i);
// and this first thing
pod.OrderID = po.ID;
pod.OrderID = orderID;
db.OrderDetails.Add(pod);
db.SaveChanges();
context class:
public class points_Order {
[Key]
public int ID { get; set; }
public string Owner { get; set; }
public DateTime Date { get; set; }
public byte Status { get; set; }
public int Total { get; set; }
//public virtual points_OrderDetails OrderDetail { get; set; }
}
public class points_OrderDetails {
[Key]
public int OrderID { get; set; }
public string OrderType { get; set; }
public int Amount { get; set; }
public int ItemID { get; set; }
public int ItemRecord { get; set; }
public string ItemCode { get; set; }
public byte Plus { get; set; }
public byte Degree { get; set; }
public string Kind { get; set; }
public string Sex { get; set; }
public string Race { get; set; }
public string Tier { get; set; }
public string SetItem { get; set; }
public string SOX { get; set; }
//public Blues Blue { get; set; }
}
public DbSet<points_Order> Order { get; set; }
public DbSet<points_OrderDetails> OrderDetails { get; set; }
im getting the error "{"Cannot insert the value NULL into column 'OrderID', table 'db.dbo.points_OrderDetails'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}"
what can i do? am i doing something wrong?
If you define a relationship from order -> order details in your model, it should work like this:
po.Details.Add(pod); // or pod.Order = po;
db.Order.Add(po);
db.SaveChanges();
EF should figure out the relations for you, no need to set ID's manually.
UPDATE: you're trying to do something that is not supported. You have a one-to-one mapping; EF does not support it the way you intend to (shared primary key). See http://weblogs.asp.net/manavi/archive/2011/05/01/associations-in-ef-4-1-code-first-part-5-one-to-one-foreign-key-associations.aspx for an explanation on how to model one-to-one in EF.