我有一个模型课程,它有几个多对多的关系,如年龄或时间。
我有这个问题:
string IDs = "1,2,3"
string[] IDList = IDs.Split(',');
return (from x in entities.Course
where x.Ages.Where(val => IDList.Contains(val.ID.ToString())).Count() == IDList.Count()
select x);
我需要为Time和其他几个属性设置相同的查询,如:
string IDs = "1,2,3"
string[] IDList = IDs.Split(',');
return (from x in entities.Course
where x.Times.Where(val => IDList.Contains(val.ID.ToString())).Count() == IDList.Count()
select x);
如何使查询更具动态性,以便我没有多个类似的查询?
由于
答案 0 :(得分:2)
您可以创建一个接受Expression
的方法(依赖于您的数据类型)并以这种方式运行查询。您需要让Ages
,Time
等实现特定的界面才能生效。
例如,假设您使用EF并且您的模型使用DbSet
s代码优先,您可以这样做:
public interface IObject
{
int ID { get; set; }
}
public class Age : IObject
{
public int ID { get; set; }
// The rest of the data
}
public class Time : IObject
{
public int ID { get; set; }
// The rest of the data
}
public class Course
{
public virtual ICollection<Age> Ages { get; set; }
public virtual ICollection<Time> Times { get; set; }
}
public class CourseContext : DbContext
{
public DbSet<Course> Course { get; set; }
}
public class Test
{
public IQueryable<Course> GetCourses(Expression<Func<Course, ICollection<IObject>>> exp)
{
var entities = new CourseContext();
string IDs = "1,2,3";
string[] IDList = IDs.Split(',');
var c = exp.Compile();
return entities.Course.Where(x => c.Invoke(x).Count(val => IDList.Contains(val.ID.ToString())) == IDList.Count());
}
public void TestMethod()
{
var times = GetCourses(c => (ICollection<IObject>)c.Times);
var ages = GetCourses(c => (ICollection<IObject>)c.Ages);
}
}
答案 1 :(得分:1)
我会创建返回不同查询结果的方法:
public IQuerable<Course> GetAllCourses() {
return entities.Course;
}
public IQueryable<Course> ByAge(IQueryable<Course> source, IEnumerable<String> ages {
return from x in source
where x.Ages.Where(val => ages.Contains(val.ID.ToString())).Count() == IDList.Count()
select x;
}
public IQuerable<Course> ByTimes(IQueryable<Course> source, IEnumerable<String> times) {
return from x in source
where x.Ages.Where(val => IDList.Contains(val.ID.ToString())).Count() == IDList.Count()
select x;
}
原因是方法封装您的查询逻辑 - 只有where
子句不同。然后,您可以传入任何来源。您甚至可以将两个查询过滤器组合为链式方法调用:
var ids = new [] { "1", "2", "3" };
var coursesByAgeAndTime = ByTime(ByAge(GetAllCourses(), ids), ids);