It is not that hard. There are 2 main ways to work using EF: Attached entities and Detached entities.
Let's suppose that we have 2 entites:
public class Foo
{
public int FooId { get; set; }
public string Description { get; set; }
public ICollection<Bar> Bars { get; set; }
}
public class Bar
{
public int BarId { get; set; }
public string Description { get; set; }
}
INSERTING
var foo = new Foo()
{
FooId = 1,
Description = "as",
Bars = new List<Bar>()
{
new Bar
{
BarId = 1,
Description = "as"
},
new Bar
{
BarId = 2,
Description = "as"
},
new Bar
{
BarId = 2,
Description = "as"
}
}
};
ctx.Foos.Add(foo);
ctx.SaveChanges();
In the above example, EF will recognize the new items, and will insert all of them.
UPDATING (ATTACHED)
var foo = ctx.Foos.Include("Bars").Where(i => i.FooId == 1).FirstOrDefault();
foreach (var bar in foo.Bars)
{
bar.Description = "changed";
}
ctx.SaveChanges();
Here we loaded foo and its bars from the context. They are already attached to the context. So, all we need to do is change the values and call SaveChanges()
. Everything will work fine.
UPDATING (DETACHED)
var foo = new Foo
{
FooId = 1,
Description = "changed3",
Bars = new List<Bar>
{
new Bar
{
BarId = 1,
Description = "changed3"
},
new Bar
{
BarId = 2,
Description = "changed3"
}
}
};
ctx.Entry(foo).State = EntityState.Modified;
foreach (var bar in foo.Bars)
{
ctx.Entry(bar).State = EntityState.Modified;
}
ctx.SaveChanges();
Here, we are working with items which already exists in database. However, they were not loaded from EF (they are not attached). EF knows nothing about them. We need to attached all of them manually and tell EF that they are modified.
REMOVING (ATTACHED)
var foo = ctx.Foos.Include("Bars").Where(i => i.FooId == 1).FirstOrDefault();
var bar = foo.Bars.First();
foo.Bars.Remove(bar);
ctx.SaveChanges();
Load bars from EF and just remove them from the collection.
REMOVING (DETACHED)
var bar = new Bar
{
BarId = 1
};
ctx.Entry(bar).State = EntityState.Deleted;
ctx.SaveChanges();
Here, Bar was not loaded from the context. So, we have to tell EF that it is deleted.
In your case, you are sending the updated object to an MVC Controller; so, you have to tell EF that StoredProcedureReport
and StoredProcedureParameters
are modified.
If all the properties are being modified you can use:
ctx.Entry(foo).State = EntityState.Modified;
//remember to do the same in all children objects
It will mark all properties as modified. Be aware that if some property was not set on view, it will be updated as an empty value.
If not all the properties are being modified, you have to specify which properties are. Like this:
context.Entry(foo).Property("Description").IsModified = true;
context.Entry(foo).Property("AnotherProperty").IsModified = true;
Hope it helps!