Create object from existing object Entity framework c# - c#

I want to copy full information of record to another in EF C#:
List<Cohort> AnYearsCohorts = oDB.Cohorts.Where(x=>x.Year == oCh.Year).ToList();
foreach (Cohort ochort in AnYearsCohorts)
{
Cohort nChort = new Cohort();
nChort = ochort;
nChort.Year = Year;
nChort.ID = 0;
oDB.Cohorts.Add(nChort);
}
oDB.SaveChanges();
But got following error:
{"The property 'ID' is part of the object's key information and cannot
be modified. "}

You probably have set ID as primary key and auto incremented so you can not change ID field explicitly in code.
Either remove ID as key or let ID increment automatically.

Related

Get the next value of a primary key field before it is created

I need to assign the value of the next ID to be created to a session variable before actually creating it.
I used the below code but idd always results in 0.
T_Order objorder = new T_Order();
int id = ((int)Session["logged_in"]);
var date = DateTime.Now;
if (Session["Order"] == null)
{
objorder.CreatedDate = DateTime.Now;
objorder.ModifiedDate = DateTime.Now;
objorder.DeliveryDate = date.AddDays(10);
objorder.User_ID = id;
objorder.OrderStatus_ID = 1;
objorder.OfferType_ID = 16;
objorder.TypeOfOrder_ID = 2;
context.T_Order.Add(objorder);
Session["Order"] = objorder.ID;
}
int idd = (int)Session["Order"];
How can I get the correct answer?
I'm assuming you're using an auto-incrementing identity field for your primary key. In which case, Entity Framework does not generate it's value until it is saved. Makes sense, how can you know what the value should be before you save it?
There's really no reason why you shouldn't save the entity at the point you create it, then assign your session variable. Holding onto it may cause you other issues like the entity becoming un-attached to the context

Does Entity framework accept/add data of an int PK that is not auto-incremented?

I have a table that has an int PK and I did not implement auto-incrementation for it. I wanted to add the data from my client application. If I try to add without auto-incremented int PK I get this exception:
An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code
Additional information: The property 'id' is part of the object's key information and cannot be modified.
Inner exception:
The property 'id' is part of the object's key information and cannot
be modified.
Well, I'm not modifying anything. I'm just trying to add a line. What's going on?
EDIT
As per request here's my code
var size = new IMF_Size();
foreach (var item in sizeFromConsolidator)
{
if (anthill.IMF_Size.Where(w => w.Brand == item.Brand && w.Category == item.Category && w.SizeCode == item.SizeCode).Count() == 0)
{
size.id = item.id;
size.SizeCode = item.SizeCode;
size.Name = item.Name;
size.Brand = item.Brand;
size.Category = item.Category;
anthill.IMF_Size.Add(size);
anthill.SaveChanges();
}
}
Your construction of size is outside of the loop.
The first time you get to the size.id = item.id; line, your size is a new entity. You set its properties, you add it to anthill, and you save the changes.
Then you go through the loop again. You get to the size.id = item.id; line again. But you haven't constructed a new size. You really are modifying an existing entity at that point.
That's exactly what the exception is telling you, too. Move the construction of size to within the loop.
Put this over the propierty of the class to DB like says Prasad Kanaparthi
[Required, Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }

Create a computed field using Entity Framework 6

Consider the following model for a EF 6 entity:
Id (int, nullable:false, identity: true)
Name (string)
Number (string).
I want number to persisted as combination of letter and id field. For example if during insert id valuse is going to be 1, I want number to be A00000001. I tried using DatabaseGenerated attribute on Number but that did not work. Problem is at time of insert EF will not know what identity value is. Is there a way to define a trigger to do so or is there some other method I can achieve this.
Thanks!
If you don't need to save the computed field to the database and are using POCOs for Entities you can just define an unmapped field like this:
[NotMapped]
public string Number
{
get { return Name + Id.ToString(); }
}
Try first inserting the item to the database:
Item myItem = new Item(){Name = "MyName"};
dbcontext.Items.Add(myItem);
dbcontext.SaveChages();
Then bring the item from the database and update it:
Item insertedItem = dbcontext.Items.Single(i => i.Id == myItem.Id);
insertedItem.Number = insertedItem.Name + insertedItem.Id.toString();
dbcontext.SaveChages();

How delete collection?

var main = (from d in db.Discounts where d.Id == discount.Id && d.UserId == userId select d).FirstOrDefault();
main.Address = "new address";
main.TermsStocks.Clear(); // I need clear collection and add new object.
foreach (var termsStock in terms)
{
main.TermsStocks.Add(new TermsStock() { Id = Guid.NewGuid(), MainId = main.Id, Title = termsStock.Title });
}
db.SaveChanges();
and I have error:
The operation failed. Unable to change the link because one or more
properties of the foreign key values ​​do not allow NULL. If you
change the connection property of the respective foreign key set to
NULL. If the foreign key value does not support NULL, must be defined
a new relationship, the foreign key property should be set to another
value other than NULL, or to remove unbound object.
how to remove the entire collection and save a new one?
You will have to remove those items form the database as well, not just from the nav property.
Roughly:
// main.TermsStocks.Clear();
foreach (var item in main.TermsStocks)
{
db.TermsStocks.Remove(item);
}
I think TermsStock object has a non nullable foreign key of Discount. Then it is not possible to have a TermsStock object without a Discount. What you are trying to do is not possible in this manner.

Entity Framework Update error

I am getting a voialation of Primary key error with the following code. I can't see for looking as to why this may be and I need to sort it out. Can anybody help with a fresh pair of eyes?
var events = (from e in nodes.Descendants("event")
select new Event
{
Event_ID = int.Parse(e.Attribute("event_id").Value),
Name = e.Attribute("name").Value,
Code = e.Attribute("code").Value,
Minute = e.Attribute("minute").Value != String.Empty ? int.Parse(e.Attribute("minute").Value) : 0,
Minute_Extra = e.Attribute("minute_extra").Value != String.Empty ? int.Parse(e.Attribute("minute_extra").Value) : 0,
Team = GetTeam(e.Attribute("team_id")),
Last_Updated = DateTime.Parse((FormatDateTime(e.Attribute("last_updated").Value)))
});
foreach (Event matchEvent in events)
{
//Check to see if this event exists
if (match.Events.Any(o => o.Event_ID == matchEvent.Event_ID))
{
Event theEvent = (from m in match.Events
where m.Event_ID == matchEvent.Event_ID
select m).FirstOrDefault();
//There is an event with this ID, so check its last updated flag
if (theEvent.Last_Updated < matchEvent.Last_Updated)
{
//Update the current event
theEvent.Event_ID = matchEvent.Event_ID;
theEvent.Name = matchEvent.Name;
theEvent.Code = matchEvent.Code;
theEvent.Minute = matchEvent.Minute;
theEvent.Minute_Extra = matchEvent.Minute_Extra;
theEvent.Team = matchEvent.Team;
theEvent.Last_Updated = matchEvent.Last_Updated;
}
}
//If the event is not there we need to add it
else
{
match.Events.Add(matchEvent);
}
myDb.SaveChanges();
UPDATE 1: The following is the error I get when SaveChanges() is called:
{"Violation of PRIMARY KEY constraint 'PK_Matches_1'. Cannot insert duplicate key in object 'dbo.Matches'.\r\nThe statement has been terminated."}
UPDATE 2: I am not using identity insert on the DB table for this as this is an import from a 3rd party Web Service where I need to retain all Ids. I am not sure if this will affect the update process with entity framework?
UPDATE 3: Ok well when I turn on identity insert the update is successful however I dont wish to have indentity insert on this table as the Ids are passed in from a WebService and I need to retain these Ids.
I'm not sure, because I'm not too hot on Entity Framework, but do you need this line?
theEvent.Event_ID = matchEvent.Event_ID;
It comes just after
//There is an event with this ID, so check its last updated flag
if (theEvent.Last_Updated < matchEvent.Last_Updated)
and I would think it's redundant, and also might cause a Primary Key error, as I don't think you can assign to a primary key once it's been created.
Update
Did a quick search, and you can't update a primary key once it's been created, so I'm pretty sure this is where your error is.
See this SO answer: Update primary key value using entity framework
I believe that your problem lies when you are updating the Event_ID property. The object you requested from your database through the match DBContext already contains that same Event_ID as the Web service. Therefore, there is no need to update this value
if (theEvent.Last_Updated < matchEvent.Last_Updated)
{
//Update the current event
theEvent.Event_ID = matchEvent.Event_ID; // <-- Delete this line.
...
}
You may ask, why it matters since both values are the same? As it so happens the DBContext keeps track of your objects and its changes. In the context itself, each property has an original and current value. When you assigned the same value to the Event_ID the context is going to interpret it as a compleately different value even though is the same.
I hope this helps.

Categories

Resources