委托 - 我的代表是否正确?
问题描述:
我创建了一个类,其中主要任务是从数据库获取数据并将其映射到某个对象。问题是同一类需要将不同的数据读取器映射到不同的对象。所以,我试图做的是走出使用委托的映射方法。委托 - 我的代表是否正确?
这是我的代码的一部分。以粗体显示重要行。
public class GetDetails<T>
{
**public delegate void DelegateMapping(T position, IDataReader reader);**
**public DelegateMapping mappingMethod;**
public T Get(T instance)
{
//Get IDs and Add to list
_db.ExecuteReader(storedProcedure.ToString(), CommandType.StoredProcedure, reader =>
{
while (reader.Read())
{
**mappingMethod(instance, reader);**
}
}, parameterList.ToArray());
return instance;
}
}
这是被调用和使用“GetDetails”类
public class PositionDB : DbBase
{
public Position GetPositionDetails(string IDs)
{
GetDetails<Position> getIDs = new GetDetails<Position>(base.db);
getIDs.storedProcedure = StoredProcedure.NET_ADM_GetPositionDetails;
//Set the Delegated Method
**getIDs.mappingMethod = MappingPositionDetails;**
//Set Parameters
getIDs.parameterList.AddInParam("PositionIds", DbType.String, IDs);
//Return the PositionId Collection
return getIDs.Get(new Position());
}
**private void MappingPositionDetails(Position position, IDataReader reader)
{
position.Id = reader["CompPositionId"];
position.Description = reader["Description"];
position.ExpirationDate = reader["ExpirationDate"];
position.Title = reader["Title"];
}**
}
的代码工作正常类。
的questios是:
- 我有没有正确使用委托?
- 这种解决方案可能会在未来造成问题(性能)?
- 还有另一个更好的解决方案?
非常感谢您
塞巴斯蒂安
答
具体回答你的问题:
- 是的,你没有使用委托正确
- 是的,它可能会导致因并发问题多线程问题
- 我想是这样的,我下面详述
一个可能的解决方案,我会提出三个转变:
- 移动则委托调用进入方法(并发问题,一个线程可能会改变,而另一种映射代表线程尝试访问它,现在试图将阅读器映射到完全不同于所提供的对象)
- 使用已经存在的通用Action/Func委托,不需要定义您自己的。
- 使用lambda表达式定义额外的方法 映射,无需
注意:2和3至少需要.NET 3.5。
用人这两个方案,你的代码应该是这样的:
public class GetDetails<T>
{
public T Get (T instance, Action<T, IDataReader> mappingMethod)
{
//Get IDs and Add to list
_db.ExecuteReader(storedProcedure.ToString(), CommandType.StoredProcedure, reader =>
{
while (reader.Read())
{
mappingMethod(instance, reader);
}
}, parameterList.ToArray());
return instance;
}
}
现在你可以在多线程环境中使用此方法为好。
编辑
才意识到它只是部分的代码。我纠正了我的建议,将其考虑在内。
答
- 是(这里也有一些改进,你可以做,见3)
- 不是性能明智的,在可发现也许有些问题。
- 我会使用多态性来完全消除代理完成的discoerability。也许使用抽象方法/类。同样取决于您为您开发的.NET版本可以使用lambdas和更简单的类型。
public Action<Position, IDataReader> Mapping { get; set; }
然后
getIDs.Mapping = (position, reader) =>
{
position.Id = reader["CompPositionId"];
position.Description = reader["Description"];
position.ExpirationDate = reader["ExpirationDate"];
position.Title = reader["Title"];
};