我们如何创建c#方法来接受不同类型的参数

时间:2016-04-07 09:07:31

标签: c# asp.net

我是asp.net的新手,并使用实体框架创建MVC项目。它大多数工作正如我所料,但有一个问题,我需要将参数传递给一个可能是不同类型的方法。我需要这个,因为我不想在每个发送相同结果的类中编写相同的方法。这是我的设置

public class BaseQuery : IOSSQuery
{
    private Entities dbcontext;

    public BaseQuery() : this(new Entities())
    {
    }
    public BaseQuery(Entities context)
    {
        this.dbcontext = context;
    }
    public List<SimpleItem> GetAllItemsFromQuery<T>( T table,Int32 skip)
    {
        List<SimpleItem> SimpleItemList = new List<SimpleItem>();
        SimpleItemList = table.Where(p => p.IsActive == true).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
        return SimpleItemList;
    }
    public virtual List<SimpleItem> GetAllItems(Int32 skip)
    {
        List<SimpleItem> SimpleItemList = new List<SimpleItem>();
        return SimpleItemList;
    }
}

然后我有一个查询类,

public class ColorQuery : BaseQuery
{
    public override List<SimpleItem> GetAllItems(Int32 skip)
    {
        return GetAllItemsFromQuery( dbcontext.tbl_color, skip)
    }
}

这是界面

public interface IOSSQuery : IDisposable
{
    List<SimpleItem> GetAllItems(Int32 skip);
}

我想从我的控制器中调用该方法,如下所示

public JsonResult Color(String range)
{
   ColorQuery query = new ColorQuery();
   List<string> ranges = range.Split(',').ToList<string>();
   var SimplePage = getAllItems(query, Convert.ToInt32(ranges[0]));
   return Json(SimplePage, JsonRequestBehavior.AllowGet);
}

public PagedData<SimpleItem> getAllItems( IOSSQuery queryObject,  int range )
{
   var SimplePage = new PagedData<SimpleItem>();
   SimplePage.total = queryObject.TotalItems();
   SimplePage.data = queryObject.GetAllItems(range);
   return SimplePage;
}

此代码在BaseQuery类

中的此行抛出错误
public List<SimpleItem> GetAllItemsFromQuery<T>( T table,Int32 skip)

Error   CS1061  'T' does not contain a definition for 'Where' and no extension method 'Where' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)

不确定如何在方法中传递不同的类型。我没试好Method to accept different types的解决方案。任何人都可以对此有所了解。谢谢你的时间。

编辑: 这是我在实体中设置的方式

public DbSet<tbl_Category> tbl_Category { get; set; }
public DbSet<tbl_color> tbl_color { get; set; }

编辑2:

我有多个不同列的表。我的想法是使用“BaseQuery”中的泛型方法为所有返回相同结果的表仍然想要使用“ColorQuery”或者如果需要的话,为不同的查询说“CategroyQuery”类。

5 个答案:

答案 0 :(得分:1)

T table似乎应限于IEnumerable<T>,因为您使用IEnumerable<T>

SimpleItemList = table.Where(p => p.IsActive == true).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();

尝试使用where(使用System.Linq)声明它:

public List<SimpleItem> GetAllItemsFromQuery<T, U>(T table,Int32 skip) where T : System.Collections.IEnumerable<U>

或者简单地说:

public List<SimpleItem> GetAllItemsFromQuery<T>(IEnumerable<T> table,Int32 skip)

答案 1 :(得分:1)

为什么不尝试使用IQueryable参数而不是通用类型参数?

public List<SimpleItem> GetAllItemsFromQuery(IQueryable table,Int32 skip)
    {
        List<SimpleItem> SimpleItemList = new List<SimpleItem>();
        SimpleItemList = table.Where(p => p.IsActive == true).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
        return SimpleItemList;
    }

答案 2 :(得分:1)

当你使GetAllItemsFromQuery方法通用(使用T作为参数类型)时,编译器不再知道它在参数table中接收的对象类型 - 所以当你调用时像IsActive这样的成员或像Where这样的扩展方法,编译器不能将它们绑定到具体的实现;事实上,它无法判断你传递的对象是偶数/拥有/那些成员。 您可以使用方法声明中的where子句为编译器提供有关它可以期望的类型的更多信息:

public List<SimpleItem> GetAllItemsFromQuery<T>( T table,Int32 skip)
    where T: IEnumerable<IEntity>
{
    List<SimpleItem> SimpleItemList = new List<SimpleItem>();
    SimpleItemList = table.Where(p => p.IsActive == true).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
    return SimpleItemList;
}

假设您的所有实体类型都实现IEntity,这将是一个包含IdNameIsActive等的接口。

如果我们能够看到Entities类型的代码,那么给您一个特定的答案会更容易,但就您尝试做的事情而言,where条款是要走的路。

答案 3 :(得分:0)

您可以使用功能名称重载。没关系。

答案 4 :(得分:0)

Sammer,

您的代码中的问题是您使用的是泛型类型参数,正如@FacticiusVir所说,编译器无法知道哪种类型,但同时您希望此类型具有Id property,Name属性和IsActive属性。

所以你可以做两件事:

  1. 使方法GetAllItemsFromQuery更具体,类似:
  2. 
            public List GetAllItemsFromQuery(IEnumerable table, Int32 skip)
            {
                List SimpleItemList = new List();
                SimpleItemList = table.Where(p => p.IsActive).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
                return SimpleItemList;
            }
    
    1. 使用限制使其具有通用性,并使用前面提到的三个属性为您的实体创建基类:

      public class tbl_color: BaseEntity
      {
      
      }
      
      public class BaseEntity
      {
          public bool IsActive { get; set; }
          public string Name { get; set; }
          public int Id { get; set; }
      }
      
      public List<SimpleItem> GetAllItemsFromQuery<T>(IEnumerable<T> table, Int32 skip) where T : BaseEntity
      {
          List<SimpleItem> SimpleItemList = new List<SimpleItem>();
          SimpleItemList = table.Where(p => p.IsActive).OrderBy(p => p.Name).Select(p => new SimpleItem { id = p.Id, Name = p.Name, IsActive = p.IsActive }).Skip(skip).Take(30).Distinct().ToList();
          return SimpleItemList;
      }