我在Windows窗体应用程序(使用Entity Framework)中工作,我的数据库中有几个表。这些表是相似的(它们具有相同数量的具有相同列名的列),除了它们(表)具有不同的名称(这意味着,我有几个实体类)。
在firstForm(MainForm)上我有一个列表框,其中包含我拥有的所有表名。当用户选择其中一个时,新表单将打开(addForm
)。在这个表单上,我有几个文本框来填充数据表。
我的问题是我想使用Entity Framework使用通用方法向表中添加数据。一般来说,如果我有一个名为Customer
的表customerName
和customerAge
列(并且它对应的类具有相同名称),我会像这样添加数据:
using(var context = new MyDbContext())
{
var newCustomer = new Customer {customerName = "Alex", customerAge = "24"};
context.Customers.Add(newCustomer);
context.SaveChanges();
}
我不想为我的数据库中的每个表编写代码。我认为,当在列表框中选择项目时,我必须将特定的类名称传递给构造函数,然后将此名称(字符串的类型)转换为特定的类,以将数据添加到与此名称关联的特定表中。
我怎么能这样做?
另一个例子 - Supplier
表:
using(var context = new MyDbContext())
{
var newSupplier = new Customer { supplierName = "Bob", supplierAge = "20" };
context.Suppliers.Add(newSupplier);
context.SaveChanges();
}
答案 0 :(得分:1)
如果所有项目的逻辑相同,您可以使用泛型并执行以下操作:
public class Writer<T> where T:class
{
private DbContext _context;
public Writer(DbContext context)
{
_context = context;
}
public void Insert(T obj)
{
_context.Set<T>().Add(obj);
_context.SaveChanges();
}
}
您必须为其提供EF上下文并指定您希望使用的类型。
希望这有助于至少指出正确的方向。
答案 1 :(得分:0)
您可以使用反射来完成此任务:
public class Person1
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
public class Person2
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
public class MyContext : DbContext
{
public MyContext() : base ("connection string") { }
public DbSet<Person1> Person1 { get; set; }
public DbSet<Person2> Person2 { get; set; }
}
具有数据库名称的示例程序可以使用反射向其添加给定实体:
//I guess you can take this values from controls on your form
string database = "Person1";
int id = 1;
string name = "Charlie";
//get type of an entity
Type entityType = this.GetType().Assembly.GetTypes().Where(t => t.Name == database).First();
//geet object of an entity class
var entity = Activator.CreateInstance(entityType);
//set properties (name and id)
entity.GetType().GetProperty("Id").SetValue(entity, id);
entity.GetType().GetProperty("Name").SetValue(entity, name);
MyContext ctx = null;
try
{
ctx = (MyContext)Activator.CreateInstance(typeof(MyContext));
//here we'll loop thorugh properties of context (through databases),
//if name match, add entity using reflection
foreach (PropertyInfo property in ctx.GetType().GetProperties())
{
if (property.Name == database)
{
var dbSet = property.GetValue(ctx);
//get Add method and invoke it with entity object
dbSet.GetType().GetMethod("Add").Invoke(dbSet, new object[]{ entity });
ctx.SaveChanges();
}
}
}
finally
{
//always remeber to call Dispose method!
if(ctx != null)
ctx.Dispose();
}
答案 2 :(得分:0)
您可以使用DbContext.Database.ExecuteSqlCommand
方法:
public class Customer : Entity
{
}
public class Supplier : Entity
{
}
public void CreateEntity(string TableName, Entity entity)
{
using(var context = new MyDbContext())
{
var name = new SqlParameter("@name", entity.customerName);
var age = new SqlParameter("@age", entity.customerAge);
context.Database.ExecuteSqlCommand($"insert into {TableName} (customerName, customerAge) values (@name, @age)",
name, age);
}
}