How do I can write a .Remove(object data)
and .Add(object data)
methods in my Repo/Controller logic when I am using in Entity Framework as the ORM? I generated Entity Model and everything works in my program, except for saving and removing entries from the database.
This is my code sample with the empty method placeholders:
class Projects
{
public static List<TProjekty> GetAll()
{
Stopwatch sw = new Stopwatch();
sw.Start();
EntitiesModel em = DB.GetDB();
List<TProjekty> projects = em.TProjekties.ToList();
sw.Stop();
Console.WriteLine("GetAllProjects: " sw.ElapsedMilliseconds);
return projects;
}
public static List<TProjekty> GetAllActiveOnly()
{
Stopwatch sw = new Stopwatch();
sw.Start();
EntitiesModel em = DB.GetDB();
List<TProjekty> projects = em.TProjekties.Where(p => p.Aktualni == true).ToList();
sw.Stop();
Console.WriteLine("GetAllProjects: " sw.ElapsedMilliseconds);
return projects;
}
public void Add(object data)
{
//var item = Entry(data);
}
public void Delete(object data)
{
//var item = Entry(data);
}
public static void Save(TProjekty project)
{
if (project == null)
{
return;
}
EntitiesModel em = DB.GetDB();
em.Add(project);
em.SaveChanges();
Checker.CheckAfterEverySave();
}
}
The code is alright without any errors, but I have empty methods for the Add
and the Delete
, because I have no idea how should I write it. I have to use .Net framework 4.8 so I cant use DB option for .Net Core.
CodePudding user response:
You should use a typed interface for this, instead of trying to use a boxed object reference, in fact your code in Save
is already doing the Add
for you!
This solution is not best practice and is only provided as a direct response to the specific question. The whole pattern of wrapping a
DbContext
in a detached way like this (detached because theTPojeckty
instances returned fromGet
methods use a differentDbContext
instance to the data persisting methods.) is generally considered an anti-pattern, in many use cases (not all) it would be better for the calling logic to use theDbContext
instance directly. You can see in this code, theAdd
andDelete
more or less call the same methods in theDbContext
.
public void Add(TProjekty project)
{
EntitiesModel em = DB.GetDB();
em.TProjektys.Add(project);
em.SaveChanges();
Checker.CheckAfterEverySave();
}
public void Delete(TProjekty project)
{
EntitiesModel em = DB.GetDB();
em.Entry(project).State = EntityState.Deleted;
em.SaveChanges();
Checker.CheckAfterEverySave();
}
NOTE: This code is assuming that the
DbSet<>
in yourDbContext
for theTProjekty
type is calledem.TProjektys
. Please update the code with a reference that matches the name of yourDbSet
before executing. It may also be the singular or proper plural forms of either:em.TProjekty
orem.TProjekties
Also: both of these methods are persisting the changes to the database, that is why I am calling out to your
Checker.CheckAfterEverySave();
in this solution.
As mentioned above, the Save
method was already performing the Add
operation, so it won't actually be updating records at all. This code for Save
should actually perform the following sequence of steps:
- detect if the provided value already exists in the database
- Add the record if it does not exist
- or Update the existing record if there is one
The schema and DbContext
implementations have not been provided, so we can't offer a definitive solution here, if you are using a simple integer based Id
key, then we could use the common convention of checking for a zero value in the Id
:
public static void Save(TProjekty project)
{
if (project == null) return;
EntitiesModel em = DB.GetDB();
if (project.Id > 0)
{
em.TProjektys.Attach(project);
em.Entry(project).State = EntityState.Modified;
}
else
{
em.TProjektys.Add(project);
}
em.SaveChanges();
Checker.CheckAfterEverySave();
}
CodePudding user response:
You shoul use Generic like in your code example.
The signature for the Add method should be :
public void Add<TProjekty>(TProjekty data)
{
//get db and use add method
}