通常我喜欢更通用一点,所以我会尝试解释我不时使用的一个非常基本的流程:
我不喜欢硬编码的态度,所以即使您的代码可以工作,它也会专门用于一种类型。我更喜欢简单的反思,首先了解它是什么 DTO,然后了解我应该使用什么存储库来操作它:
例如:
public class ImportProvider
{
private readonly string _path;
private readonly ObjectResolver _objectResolver;
public ImportProvider(string path)
{
_path = path;
_objectResolver = new ObjectResolver();
}
public void Import()
{
var filePaths = Directory.GetFiles(_path, "*.csv");
foreach (var filePath in filePaths)
{
var fileName = Path.GetFileName(filePath);
var className = fileName.Remove(fileName.Length-4);
using (var reader = new CsvFileReader(filePath))
{
var row = new CsvRow();
var repository = (DaoBase)_objectResolver.Resolve("DAL.Repository", className + "Dao");
while (reader.ReadRow(row))
{
var dtoInstance = (DtoBase)_objectResolver.Resolve("DAL.DTO", className + "Dto");
dtoInstance.FillInstance(row.ToArray());
repository.Save(dtoInstance);
}
}
}
}
}
上面是一个非常基本的类,负责导入数据。不过这段代码如何解析CSV文件(CsvFileReader),重要的是“CsvRow”是一个简单的List。
下面是ObjectResolver的实现:
public class ObjectResolver
{
private readonly Assembly _myDal;
public ObjectResolver()
{
_myDal = Assembly.Load("DAL");
}
public object Resolve(string nameSpace, string name)
{
var myLoadClass = _myDal.GetType(nameSpace + "." + name);
return Activator.CreateInstance(myLoadClass);
}
}
这个想法是简单地遵循命名约定,在我的例子中,使用“Dto”后缀来反映实例,使用“Dao”后缀来反映负责的 dao。 Dto 或 Dao 的全名可以取自 csv 名称或标题(如您所愿)
下一步是填充 Dto,每个 dto 或实现以下简单抽象:
public abstract class DtoBase
{
public abstract void FillInstance(params string[] parameters);
}
由于每个Dto“知道”他的结构(就像你知道在数据库中创建一个合适的表一样),它可以很容易地实现FillInstanceMethod,这里是一个简单的Dto示例:
public class ProductDto : DtoBase
{
public int ProductId { get; set; }
public double Weight { get; set; }
public int FamilyId { get; set; }
public override void FillInstance(params string[] parameters)
{
ProductId = int.Parse(parameters[0]);
Weight = double.Parse(parameters[1]);
FamilyId = int.Parse(parameters[2]);
}
}
在你的 Dto 填充数据之后,你应该找到合适的 Dao 来处理它
这基本上发生在 Import() 方法的这一行中的反射中:
var repository = (DaoBase)_objectResolver.Resolve("DAL.Repository", className + "Dao");
在我的例子中,Dao 实现了一个抽象基类——但这与您的问题无关,您的 DaoBase 可以是一个带有单个 Save() 方法的简单抽象。
这样你就有了一个专门的 Dao 来 CRUD 你的 Dto - 每个 Dao 都知道如何为它的相关 Dto 保存。下面是 ProductDto 对应的 ProductDao:
public class ProductDao : DaoBase
{
private const string InsertProductQuery = @"SET foreign_key_checks = 0;
Insert into product (productID, weight, familyID)
VALUES (@productId, @weight, @familyId);
SET foreign_key_checks = 1;";
public override void Save(DtoBase dto)
{
var productToSave = dto as ProductDto;
var saveproductCommand = GetDbCommand(InsertProductQuery);
if (productToSave != null)
{
saveproductCommand.Parameters.Add(CreateParameter("@productId", productToSave.ProductId));
saveproductCommand.Parameters.Add(CreateParameter("@weight", productToSave.Weight));
saveproductCommand.Parameters.Add(CreateParameter("@familyId", productToSave.FamilyId));
ExecuteNonQuery(ref saveproductCommand);
}
}
}
请忽略 CreateParameter() 方法,因为它是基类的抽象。您可以只使用 CreateSqlParameter 或 CreateDataParameter 等。
请注意,这是一个真正幼稚的实现 - 您可以轻松地对其进行更好的改造,具体取决于您的需求。