Linq 实体框架代码优先动态查询

Linq 实体框架代码优先动态查询,linq,entity-framework,Linq,Entity Framework,这段代码很可怕,我只搜索一个属性(CompanyName)。如何动态地编写此查询,或者在任何情况下编写得更好 public List<SubContractor> GetSearchSubcontractorList() { var list = CacheObjects.Subcontractors; var searchItem = string.Empty; if (string.IsNullOrWhiteSpace

这段代码很可怕,我只搜索一个属性(CompanyName)。如何动态地编写此查询,或者在任何情况下编写得更好

   public List<SubContractor> GetSearchSubcontractorList()
    {
        var list = CacheObjects.Subcontractors;
        var searchItem = string.Empty;
        if (string.IsNullOrWhiteSpace(this.SearchCompanyName) == false)
        {
            var indexes = this.SearchCompanyName.IndexOfAll("*").ToList();
            if (indexes.Any() == false)
            {
                list = list.Where(x => x.CompanyName == this.SearchCompanyName).ToList();
            }

            if (indexes.Count() == 1)
            {
                if (this.SearchCompanyName.StartsWith("*"))
                {
                    searchItem = this.SearchCompanyName.Replace("*", string.Empty);
                    list = list.Where(x => x.CompanyName.EndsWith(searchItem)).ToList();
                }
                else
                {
                    searchItem = this.SearchCompanyName.Replace("*", string.Empty);
                    list = list.Where(x => x.CompanyName.StartsWith(searchItem)).ToList();
                }
            }

            if (indexes.Count() == 2)
            {
                searchItem = this.SearchCompanyName.Replace("*", string.Empty);
                list = list.Where(x => x.CompanyName.Contains(searchItem)).ToList();
            }
        }

        return list;
    }
public List GetSearchSubcontractorList()
{
var list=CacheObjects.contractor;
var searchItem=string.Empty;
if(string.IsNullOrWhiteSpace(this.SearchCompanyName)==false)
{
var index=this.SearchCompanyName.IndexOfAll(“*”).ToList();
if(index.Any()==false)
{
list=list.Where(x=>x.CompanyName==this.SearchCompanyName.ToList();
}
if(index.Count()==1)
{
if(this.SearchCompanyName.StartsWith(“*”))
{
searchItem=this.SearchCompanyName.Replace(“*”,string.Empty);
list=list.Where(x=>x.CompanyName.EndsWith(searchItem)).ToList();
}
其他的
{
searchItem=this.SearchCompanyName.Replace(“*”,string.Empty);
list=list.Where(x=>x.CompanyName.StartsWith(searchItem)).ToList();
}
}
if(index.Count()==2)
{
searchItem=this.SearchCompanyName.Replace(“*”,string.Empty);
list=list.Where(x=>x.CompanyName.Contains(searchItem)).ToList();
}
}
退货清单;
}

哦,对不起,我听错了。我编辑,查看新的解决方案。我想你只有4个不同的案例需要测试,对吗?无通配符,以通配符开始,以通配符结束,两端均为通配符。新的解决方案使用延迟查询执行,以便您可以继续使用更多属性构建查询。公平的警告,仍然没有遵守

    var filteredSubcontractors = (from s in list
                             select s);

    if (string.IsNullOrWhiteSpace(this.SearchCompanyName) == false)
    {
        searchItem = this.SearchCompanyName.Replace("*", string.Empty);

        if (!SearchCompanyName.Contains("*"))
        {
            filteredSubcontractors = (from s in filteredSubcontractors 
                             where s.CompanyName == this.SearchCompanyName
                             select s);
        }
        else if(SearchCompanyName.StartsWith("*"))
        {      
            filteredSubcontractors = (from s in filteredSubcontractors 
                             where s.CompanyName.EndsWith(searchItem)
                             select s);
        }
        else if(SearchCompanyName.EndsWith("*"))
        {
            filteredSubcontractors = (from s in filteredSubcontractors 
                             where s.CompanyName.StartsWith(searchItem)
                             select s);
        }
        else
        {
            filteredSubcontractors = (from s in filteredSubcontractors 
                             where s.CompanyName.Contains(searchItem)
                             select s);
        }
    }

    ...
    //Repeat for as many other properties that you want to filter on
    ...

    //All the conditions that you added will not actually be evaluated 
    //until this line is executed.
    var result = filteredSubcontractors.ToList();

    return result;

您还可以查看此堆栈溢出问题。这里还有很多其他的想法(可能比我的好)

*是用于搜索的通配符。如果不清楚,我会道歉。所以*要么不存在,要么在开头或结尾,要么两者都存在。这就是为什么我要这样写代码。哦,明白了,看看新的答案,看看是否更好。是的,它更好,尽管它不能正常工作。我需要在StartWith的条件之前检查搜索字符串是否以*开头和结尾。然而,我的另一个担忧是,我必须对所有其他搜索条件执行相同的代码,例如SearchCompanyAddress。我无法找到一种方法来抽象此代码以避免重复我自己。请重新编辑。您最终仍然会得到相当数量的代码,但至少对于您要测试的每个新属性,它不会是指数级的。我认为对您有帮助的是阅读一下linq中关于延迟查询执行的内容。它允许您动态构建查询。谢谢您。当searchstring看起来像@abc@时,应该执行final Contains子句,并且在代码中永远不会到达它。这就是为什么我用我最初的方式写了一些代码。从更广泛的问题来看,我认为您可能是对的,但令我惊讶的是,没有一种方法可以抽象此代码。延迟加载没有任何意义,因为我首先查询的是缓存对象的集合,而不是数据库。