我是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”类。
答案 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
,这将是一个包含Id
,Name
,IsActive
等的接口。
如果我们能够看到Entities
类型的代码,那么给您一个特定的答案会更容易,但就您尝试做的事情而言,where
条款是要走的路。
答案 3 :(得分:0)
您可以使用功能名称重载。没关系。
答案 4 :(得分:0)
Sammer,
您的代码中的问题是您使用的是泛型类型参数,正如@FacticiusVir所说,编译器无法知道哪种类型,但同时您希望此类型具有Id property,Name属性和IsActive属性。
所以你可以做两件事:
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;
}
使用限制使其具有通用性,并使用前面提到的三个属性为您的实体创建基类:
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;
}