Reputation: 1631
Usually, I create new database entites with dbContext.MyClass.Create()
. In my current application, I need to create such an entity from within an extension method of another model class.
I have the two classes DataEntry
and WorkSchedule
, where one DataEntry can contain multiple WorkSchedules. Therefore, I added a method DataEntry.FillOrUpdateFromWCF()
, which calls a web service and updates some fields. So far, so good.
This method also needs to create new WorkSchedules for this same DataEntry in some cases. The problem is, that I, as far as I know, have no reference to the current DataEntry's database context. Sure, I could just create them with new WorkSchedule()
, but that would not update them after saving, right?
So is there something like a this.ThisEntitysDatabaseContext.WorkSchedule.Create()
method from within the DataEntry
class?
public partial class DataEntry {
public async Task FillOrUpdate() {
WcfData[] data = GetSomeDataFromWCF();
foreach(WcfData wd in data) {
WorkSchedule ws = this.PathToContext.WorkSchedule.Create();
ws.Stuff = "test";
this.WorkSchedules.Add(ws);
}
}
}
Upvotes: 1
Views: 1260
Reputation: 30464
Actually, you don't need to ask the DbContext to Create a DataEntry for you. In fact, this is quite uncommon.
Usually you create the object using new
, then fill all the properties, except the primary keys and Add
the object to the dbContext
using (var dbContext = new MyDbContext())
{
DataEntry entryToAdd = new DataEntry()
{
// fill the properties you want, leave the primary key zero (default value)
Name = ...
Date = ...
WorkShedules = ...
};
// add the DataEntry to the database and save the changes
dbContext.Add(entryToAdd);
dbContext.SaveChanges();
}
For the WorkSchedules
you can use your own function, but you can also assign a value using operator new:
WorkSchedules = new List<WorkSchedule>()
{
new WorkSchedule() {Name = "...", ...},
new WorkSchedule() {Name = "...", ...},
new WorkSchedule() {Name = "...", ...},
},
Note: do not fill the primary key of the work schedule, nor the foreign key of the DataEntry
that this Workschedule
belongs to, after all, you don't know the value yet.
Entity framework is smart enough to understand the one-to-many relationship, and will add the proper items to the database, with the proper values for the foreign keys.
Upvotes: 1
Reputation: 151604
Sure, I could just create them with new WorkSchedule(), but that would not update them after saving, right?
It would, as long as you attach them to a tracked entity. You really don't want access to the DbContext in an entity class, that's an antipattern. You also should reconsider whether you want your entity classes to contain any logic, but that's up for debate.
So if you have something like this:
public class DataEntry
{
public ICollection<WorkSchedule> Schedules { get; set; }
public void DoWork()
{
Schedules.Add(new WorkSchedule
{
Start = DateTime.Now
});
}
}
Then this will add the proper record and foreign key (assuming that's all set up properly):
using (var db = new YourContext())
{
var dataEntry = db.DataEntries.Single(d => d.Id == 42);
dataEntry.DoWork();
db.SaveChanges();
}
Upvotes: 2