将两个方法合并为一个泛型方法
本文关键字:一个 泛型方法 两个 方法 合并 | 更新日期: 2023-09-27 18:22:17
我的DAL中有两个方法,它们完全相同,并基于作为参数支持的主键返回数据库行。DB上下文是linqtoSQL。一个传入字符串参数,另一个传入int参数。我认为必须使用泛型来创建一个接受string或int但不确定如何接受的方法。
/// <summary>
/// Select table row by integer Primary Key Value
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id">The PK value to search for</param>
/// <returns>Single matching PK to id</returns>
public T SelectRowByPk<T>(int id) where T : class
{
using (var dc = new DBDataContext())
{
// Get the table by the type passed in
var table = dc.GetTable<T>();
// Get the metamodel mappings (database to domain objects)
MetaModel modelMap = table.Context.Mapping;
// Get the data members for this type
ReadOnlyCollection<MetaDataMember> dataMembers =
modelMap.GetMetaType(typeof (T)).DataMembers;
// Find the primary key field name by checking for IsPrimaryKey
string pk = (dataMembers.Single(m => m.IsPrimaryKey)).Name;
// Return a single object where the id argument matches the primary key
field value
return table.SingleOrDefault(delegate(T t)
{
int memberId =
Convert.ToInt16(t.GetType().GetProperty(pk).GetValue(t, null));
return memberId == id;
});
}
}
/// <summary>
/// Select table row by Varchar Primary Key Value
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id">The PK value to search for</param>
/// <returns>Single matching PK to id</returns>
public T SelectRowByVarcharPk<T>(string id) where T : class
{
using (var dc = new DBDataContext())
{
// Get the table by the type passed in
var table = dc.GetTable<T>();
// Get the metamodel mappings (database to domain objects)
MetaModel modelMap = table.Context.Mapping;
// Get the data members for this type
ReadOnlyCollection<MetaDataMember> dataMembers =
modelMap.GetMetaType(typeof(T)).DataMembers;
// Find the primary key field name by checking for IsPrimaryKey
string pk = (dataMembers.Single(m => m.IsPrimaryKey)).Name;
// Return a single object where the id argument matches the primary key
field value
return table.SingleOrDefault(delegate(T t)
{
string memberId =
t.GetType().GetProperty(pk).GetValue(t, null).ToString();
return memberId == id;
});
}
}
您不能直接使用泛型将两个方法组合为一个方法,但是您可以将一些重构与泛型结合使用,以获得干净的设计:
制作一个私有方法,使用两个通用参数来完成繁重的工作,一个用于实体类型,另一个用于主键类型:
private T SelectRowById<T, TId>(TId id) where T : class
{
using (var dc = new DBDataContext())
{
// Get the table by the type passed in
var table = dc.GetTable<T>();
// Get the metamodel mappings (database to domain objects)
MetaModel modelMap = table.Context.Mapping;
// Get the data members for this type
ReadOnlyCollection<MetaDataMember> dataMembers =
modelMap.GetMetaType(typeof(T)).DataMembers;
// Find the primary key field name by checking for IsPrimaryKey
string pk = (dataMembers.Single(m => m.IsPrimaryKey)).Name;
// Return a single object where the id argument matches the primary key
field value
return table.SingleOrDefault(delegate(T t)
{
var memberId =
(TId)t.GetType().GetProperty(pk).GetValue(t, null);
return memberId == id;
});
}
}
之后,您可以为使用此私有方法的特定id类型声明两个公共方法:
public T SelectRowById<T>(string id) where T : class
{
return SelectRowById<T, string>(id);
}
public T SelectRowById<T>(int id) where T : class
{
return SelectRowById<T, int>(id);
}
通过这种方式,您将拥有一个干净的公共界面,代码重复最少。
public T SelectRowByPk<T>(T id)
{
//you'll need to do some run-time type checking of 'id' here since string and int
//can't be constrained by a type parameter constraint in the same method
}
指定类型参数的要点之一是可以具有动态参数类型。在本例中,"id"将变为您指定的任何类型。