Добавить запись в коллекцию List<> из метода класса. net5
Есть классы.
public class employee
{
public int id;
public string Name;
}
public class Job
{
public int id;
public string JobName;
}
Они разные и их много. Объявляем их как list
List<employee> dtemployee = new List<employee>();
List<Job> dtJob = new List<Job>();
Заполнить их можно, например, так (это работает):
dtemployee.Add(new employee { id = 1, Name = "Тестовый employee" );
Но мне нужно его заполнить из метода другого класса. Причём в качестве параметра передать list можем передать employee, а можем job. Ну и еще много других. Пишем класс, в который передаем этот IList:
public class dbEngine
{
public fill(IList table ,string con, string command)
{
var x = new table(); //ошибка Не знаю как правильно сделать
table.Add(x);
}
}
Вызов предполагается такой.
dbEngine db = new dbEngine();
db.fill(dtemployee,con,"Select * from employee");
db.fill(dtJob,con,"Select * from job");
В общем проблема - как создать запись и добавить в список из класса dbEngine, учитывая, что там разные классы. Подскажите, как правильно создать запись и ее добавить? Пусть пустую. Я не знаю, какой класс будет передан. Нужно это как-то определить. Как? С Property как передать параметры в зависимости от имени я представляю.
Задача будет такая. Я должен написать универсальный метод, который будет делать select из базы данных и заполнять нужные коллекции.
Сторонние фреймоврки не применять.
Спасибо.
Ответы (1 шт):
Такие "универсальные" методы получения данных из БД обычно создают больше проблем чем решают. Тем не менее, я отвечу. С одновременной правкой именования, стиля и пр.
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Job
{
public int Id { get; set; }
public string JobName { get; set; }
}
public class DbEngine
{
private readonly string _connectionString = "...";
public void Fill<T>(IList<T> list, string command, Func<SqlDataReader, T> func)
{
using (var con = new SqlConnection(_connectionString))
{
con.Open();
using (var cmd = new SqlCommand(command, con))
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var item = func(reader);
list.Add(item);
}
}
}
}
}
Использование:
var employees = new List<Employee>();
var jobs = new List<Job>();
DbEngine db = new DbEngine();
db.Fill(employees, "Select [id], [name] from employee",
reader => new Employee { Id = reader.GetInt32(0), Name = reader.GetString(1) });
db.Fill(jobs, "Select [id], [name] from job",
reader => new Job { Id = reader.GetInt32(0), JobName = reader.GetString(1) });
Так как классы Employee и Job не имеют общего предка, мы не можем легко создавать их экземпляры внутри метода Fill. Конечно, это можно сделать с помощью рефлексии, но это будет медленно и склонно к ошибкам.
В данном случае это решено с помощью делегата на функцию, в которой мы создаём экземпляр нужного класса (это сделано лямбдой).
Если сущности имеют одинаковый набор похожих свойств, то можно выделить их в интерфейс (или базовый класс).
public interface IEntity
{
int Id { get; set; }
string Name { get; set; }
}
public class Employee : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Job : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
public void Fill<T>(IList<T> list, string command)
where T : IEntity, new()
{
using (var con = new SqlConnection(_connectionString))
{
con.Open();
using (var cmd = new SqlCommand(command, con))
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var item = new T();
item.Id = reader.GetInt32(0);
item.Name = reader.GetString(1);
list.Add(item);
}
}
}
}
В этом случае вызов метода становится проще:
db.Fill(employees, "Select [id], [name] from employee");
db.Fill(jobs, "Select [id], [name] from job");