我有两个类似的方法,基本上只对不同的对象做同样的事情。 如果可能的话,制作通用方法的最佳方法是什么?
这两个对象:
public class StoreObject {
int Key;
string Address;
string Country;
int Latitude;
int Longitude;
}
public class ProjectObject {
int ProjectKey;
string Address;
string Description;
}
我可能想要制作通用的两种方法:
public StoreObject GetStoreByKey(int key)
{
using (DBEntities dbe = new DBEntities())
{
StoreObject so = new StoreObject();
var storeObject = (from s in dbe.StoreTables
where s.Key == key
select s).First();
so.Key = storeObject.key;
so.Address = storeObject.address;
so.Country = storeObject.country;
so.Latitude = storeObject.latitude;
so.Longitude = storeObject.longitude;
return so;
}
}
public ProjectObject GetProjectByKey(int projectKey)
{
using (DBEntities dbe = new DBEntities())
{
ProjectObject po = new ProjectObject();
var projectObject = (from p in dbe.ProjectTables
where p.ProjectKey == projectKey
select p).First();
po.Key = projectObject.p_key;
po.Address = projectObject.p_address;
po.Description = projectObject.p_description;
return po;
}
}
我必须注意:
- 我无法控制表字段的命名方式(即.p_description)
例如,DB中的StoreTable可能有其他属性(如电话,邮政编码等),但我只想展示我在代码中显示的内容。
- ProjectTable也是如此。
答案 0 :(得分:3)
嗯,棘手的部分是你的实体有不同的属性,所以使用泛型来填充一个方法中的不同属性是不值得的。但是您可以返回整个对象,然后只使用您感兴趣的属性。
public T GetEntityByKey<T>(int key)
{
using (DBEntities dbe = new DBEntities())
{
return = dbe.StoreTables.Set<T>.Find(new object[] {key});
}
}
并使用它
StoreObject so = GetEntityByKey<StoreObject>(123);
if(so != null)
{
int lat = so.Latitude;
}
答案 1 :(得分:2)
您确实可以抽象出所返回的类型,并将using
计算在内,但对于其余部分,您需要在请求的类型上切换,或者在字段中传递反射以作为参数进行检索要使用的数据库查询。
前者是不好的做法,并没有带来什么等式,而后者是昂贵的,可能会变得混乱。
除非你有许多类似的外观方法,否则这对于泛型来说并不是一个好的候选者,在这种情况下我会采用反射方法。
HTH,
巴布。
答案 2 :(得分:2)
这不太可能是您的整个“工作单元”,因此在这些方法中使用新的DBEntities()
上下文可能是您问题的根源。
创建一个Repository
类,其中包含单个Web请求的DBEntities
类实例(或您的应用程序中的任何其他请求单元),并且其中包含这些方法这里消除重复代码的更好方法。 using()
的范围超出了这些方法,并且希望与您的网络请求或其他时间单位相关联。
作为一个选项而不是创建一个新类,您还可以扩展DBEntities
部分类以包含这些方法(假设这是生成的代码)。
答案 3 :(得分:2)
每种方法基本上都有两种不同的功能:
第一部分由Steve Mallory解决。
对于第二部分,您可以使用映射器框架来处理从一个实例到另一个实例的值复制。由于每种类型的名称不匹配,您需要告诉它如何映射名称(在您的示例中,添加“p_”并使其为小写)。一种可能性是Emit Mapper。
如果你 分解所有的共性,那就像是:
public TResult GetById<TResult, TEntity>(int id)
{
using (DBEntities dbe = new DBEntities())
{
T result = dbe.StoreTables.Set<T>.Find(new object[] {key});
var mapper = ObjectMapperManager.DefaultInstance
.GetMapper<TEntity, TResult>(
new DefaultMapConfig().MatchMembers((m1, m2) => "p_" + m1.ToLower() == m2));
return mapper.Map(result);
}
}