C# 如何从两个相似但不同的方法中创建通用方法?

C# 如何从两个相似但不同的方法中创建通用方法?,c#,generics,ado.net,C#,Generics,Ado.net,我有两个相似的方法,基本上只对不同的对象做相同的事情。 如果可能的话,用这种方法生成通用方法的最佳方法是什么 这两个对象: 我可能希望将两种方法转换为泛型: 我必须注意: -我无法控制表格字段的命名方式(即p_描述)。 -例如,数据库中的StoreTable可能有其他属性(如电话、邮政编码等),但我只对显示代码中显示的内容感兴趣。 -ProjectTable也是如此。您确实可以提取返回的类型,并使用对进行因子化,但对于其余部分,您需要打开请求的类型,或者在字段中传递反射以作为参数检索,并使用

我有两个相似的方法,基本上只对不同的对象做相同的事情。 如果可能的话,用这种方法生成通用方法的最佳方法是什么

这两个对象:

我可能希望将两种方法转换为泛型:

我必须注意:
-我无法控制表格字段的命名方式(即p_描述)。
-例如,数据库中的StoreTable可能有其他属性(如电话、邮政编码等),但我只对显示代码中显示的内容感兴趣。

-ProjectTable也是如此。

您确实可以提取返回的类型,并使用对
进行因子化,但对于其余部分,您需要打开请求的类型,或者在字段中传递反射以作为参数检索,并使用DB查询

前者是一种糟糕的做法,几乎不会带来什么好处,而后者代价高昂,可能会变得一团糟

这并不是泛型的好选择,除非您有许多类似的方法,在这种情况下,我会选择反射方法

嗯,


Bab.

这不太可能是您的整个“工作单元”,因此在每个方法中使用新的
DBEntities()
上下文可能是您的问题的根源

创建一个
存储库
类,该类包含单个web请求(或应用程序中的任何其他请求单元)的
DBEntities
类的实例,并且其中包含这些方法,这将是消除重复代码的更好方法。然后,
using()
的范围就超出了这些方法的范围,并希望与您的web请求或其他时间单位相关联


作为一种替代创建新类的选项,您还可以扩展
DBEntities
分部类以包含类似的方法(假设这是生成的代码)。

好吧,棘手的部分是您的实体具有不同的属性,因此在一个方法中使用泛型填充不同的属性是不值得的。但是您可以返回整个对象,然后只使用您感兴趣的属性

public T GetEntityByKey<T>(int key)
{
  using (DBEntities dbe = new DBEntities())
  {
    return = dbe.StoreTables.Set<T>.Find(new object[] {key});
  }
}
public T GetEntityByKey(int键)
{
使用(DBEntities dbe=new DBEntities())
{
return=dbe.StoreTables.Set.Find(新对象[]{key});
}
}
以及如何使用它

StoreObject so  = GetEntityByKey<StoreObject>(123);
if(so != null)
{
    int lat = so.Latitude;
} 
StoreObject so=GetEntityByKey(123);
if(so!=null)
{
int lat=so纬度;
} 

每种方法都有两种不同的功能:

  • 查询实体
  • 将该实体映射到其他类型
  • 第一部分由Steve Mallory提出

    对于第二部分,您可以使用映射器框架处理从一个实例到另一个实例的值复制。由于每种类型的名称不匹配,您需要告诉它如何映射名称(在您的示例中,添加“p_”并使其小写)。一种可能性是

    如果你要排除所有的共性,它会是这样的:

    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);      
        }
    }
    
    public TResult GetById(int-id)
    {
    使用(DBEntities dbe=new DBEntities())
    {        
    T result=dbe.StoreTables.Set.Find(新对象[]{key});
    var mapper=objectmappermager.DefaultInstance
    .GetMapper(
    新的DefaultMapConfig().MatchMembers((m1,m2)=>“p_”+m1.ToLower()==m2));
    返回mapper.Map(结果);
    }
    }
    
    这些方法并不相似。几乎每一行都不同。可以将表达式作为where子句传递,但这只会使事情变得更复杂。这些方法中的每一种都确切地知道如何处理它们所处理的对象。我认为它已经被抽象了。好吧,我不得不说有相似之处,虽然我同意它已经被抽象了,但我想我会试着问一下,以防其他人有想法让它变得更抽象。好主意,但我还是想尝试将这些转化为通用。我感谢大家的意见,但我不得不同意史蒂夫的答案。(不过我需要换一些东西,因为我不仅仅是从储物台上买东西)嗯。。我会考虑这一点,但是手动映射这三个字段可能会更简单。我已经考虑过反射,但我想我会试着看看它是否可以作为一个通用的。
    StoreObject so  = GetEntityByKey<StoreObject>(123);
    if(so != null)
    {
        int lat = so.Latitude;
    } 
    
    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);      
        }
    }