C# 通过数据访问层从数据库中获取数据的智能方法?

C# 通过数据访问层从数据库中获取数据的智能方法?,c#,sql-server,entity-framework,data-access-layer,C#,Sql Server,Entity Framework,Data Access Layer,我有一个包含许多不同数据集的数据库。我想根据许多不同的参数轻松搜索不同的数据集,例如,我目前拥有: public List<Dataset> GetAllDatasetsByMethod(Method method) var datasets = from b in db.Dataset where b.TargetMaterial.Name.ToLower() == material.Name.ToLower() s

我有一个包含许多不同数据集的数据库。我想根据许多不同的参数轻松搜索不同的数据集,例如,我目前拥有:

public List<Dataset> GetAllDatasetsByMethod(Method method)
var datasets = from b in db.Dataset
                where b.TargetMaterial.Name.ToLower() == material.Name.ToLower()
                select b;
然后我有另一种方法,看起来像这样:

public List<Dataset> GetAllDatasetsByTargetMaterial(TargetMaterial material)
var datasets = from b in db.Dataset
                where b.TargetMaterial.Name.ToLower() == material.Name.ToLower()
                select b;

我得到了很多这样的方法(比如10-15),在一个唯一的id或名称上比较乙醚。我需要做更多,但我开始觉得我在重复我自己,就我所学到的。那么有没有更聪明的方法来实现这一点呢?

如果方法扩散是您的问题,而您所做的只是更改where语句,那么您可以使用Func作为参数,只需提供作为Func所需的逻辑即可

var datasets = from b in db.Dataset
                where b.TargetMaterial.Name.ToLower() == material.Name.ToLower()
                select b;
例如:

var datasets = from b in db.Dataset
                where b.TargetMaterial.Name.ToLower() == material.Name.ToLower()
                select b;
公共IEnumerable GetAllDataSetBy(Func Func){ 返回db.DataSet.Where(b=>func(b)); } 公共MyType GetSingle(Func Func){ 返回db.DataSet.Single(b=>func(b)); }
创建一个包含所有不同查询参数变体的类,如

var datasets = from b in db.Dataset
                where b.TargetMaterial.Name.ToLower() == material.Name.ToLower()
                select b;
public class MyTypeQueryParameters
{
    public int? Id {get; set;}
    public string MaterialName {get; set;}
}
然后,您可以像内部API一样设计数据访问层,并使用如下方法:

var datasets = from b in db.Dataset
                where b.TargetMaterial.Name.ToLower() == material.Name.ToLower()
                select b;
public List<DataSet> GetDataSets(MyTypeQueryParameters parameters) {
    var query = db.DataSet.AsQueryable;
    if (parameters.Id != null) 
    {
        query = query.Where(x => x.Id == parameters.Id.Value);
    }

    if (!string.IsNullOrWhitespace(MaterialName))
    {
        query = query.Where(x => x.TargetMaterial.Name == parameters.MaterialName);
    }

    return query.ToList();
}
公共列表GetDataSet(MyTypeQueryParameters参数){
var query=db.DataSet.AsQueryable;
if(parameters.Id!=null)
{
query=query.Where(x=>x.Id==parameters.Id.Value);
}
如果(!string.IsNullOrWhitespace(MaterialName))
{
query=query.Where(x=>x.TargetMaterial.Name==parameters.MaterialName);
}
返回query.ToList();
}

有一些方法可以稍微清理方法的逻辑,但这就是我开始的方式,所以你不会得到大量基于查询过滤器的不同方法。

我已经考虑过这样做,我的问题是有时多个条件必须为真(因此,请同时查找具有materialname和id的所有示例)这不就是创建一个巨大的方法,而不是使用大量的if?查询是可组合的,所以在我的示例中,您只需要去掉else语句。因此,如果指定了ID,您将添加ID where子句,如果指定了material name,您还将添加带有名称的where子句。如果只有一个查询,您将只为其添加where子句仅指定了一个。只有在
.ToList()
it之后才会执行查询,因此您可以添加尽可能多的
query=query.Where(x=>Where)
子句your want.Done。我所做的就是删除else关键字。现在,如果两个都指定了,那么查询将同时包含两个where子句。好的,我看到了你所做的,我想,你会得到所有具有给定id的数据集,然后是所有具有给定名称的数据集。但我有时这两个都需要为真。因此,如果同时给定id和名称,它应该为真返回具有这两个属性的数据集(因此,如果有一个具有方法id但没有目标材质名称的数据集,那么它就不应该包含该属性)?我不能这样做,是吗?我想您可能会因为不了解IQueryables和EF的工作原理而感到困扰。当我执行
query=query.Where(x=>x.id==id)时
我没有从数据库中获取所有具有匹配ID的数据集。我所做的是生成一个SQL查询,该查询将检索具有匹配ID的数据集,但我只生成了查询,而没有执行查询。然后,第二个where子句实质上添加了一个“and”ToList()然后执行包含两个where子句的查询。
var datasets = from b in db.Dataset
                where b.TargetMaterial.Name.ToLower() == material.Name.ToLower()
                select b;