我正在尝试按照使用实体框架创建动态查询中的模式在几个表中创建搜索功能
我有 3 张桌子:
People:
pk ID
varchar FirstName
varchar LastName
fk AddressMap_ID
AddressMap:
pk ID
Address:
pk ID
varchar StreetName
varchar StreeNumber
fk AddressMap_ID
多个人可以住在一个地址。我传入一个 Search 模型,并填充 results 属性:
public class Search
{
public string streetname { get; set; }
public string streetnumber { get; set; }
public string fname { get; set; }
public string lname { get; set; }
public IEnumerable<Results> results { get; set; }
}
public class Results
{
public int AddressID { get; set; }
public string StreetNumber { get; set; }
public string StreetName { get; set; }
public IEnumerable<PeopleResults> people { get; set; }
}
public class PeopleResults
{
public int personID { get; set; }
public string First { get; set; }
public string Last { get; set; }
}
如果我过滤地址或名称+地址,则此方法有效:
public void GetResults(Search model)
{
Entities _context;
_context = new Entities();
var addr = from a in _context.Addresses
select a;
addr = addr.Where(filter => filter.StreetNumber == model.streetnumber);
addr = addr.Where(filter => filter.StreetName == model.streetname);
addr = from a in addr
group a by a.AddressMap_ID into addrs
select addrs.FirstOrDefault();
var ppl = from p in addr.SelectMany(p => p.AddressMap.People) select p;
ppl = ppl.Where(filter => filter.FirstName.StartsWith(model.fname));
ppl = ppl.Where(filter => filter.LastName.StartsWith(model.lname));
model.results = from a in addr
select new Results
{
AddressID = a.ID,
StreetName = a.StreetName,
StreetNumber = a.StreetNumber,
people = from p in ppl
select new PeopleResults
{
First = p.FirstName,
Last = p.LastName
}
};
}
但是,如果我只是尝试过滤一个名称,它会返回一个笛卡尔连接 - 每个地址都包含所有匹配的人。
有 3 种搜索方式:仅按地址过滤、按地址 + 名称过滤或仅按名称过滤。
所以如果有人搜索“123 Main”,结果应该是
123 Main St SticksVille Joe Smith
Jane Smith
Mary Smith
123 Main St Bedrock Fred Flintstone
Wilma Flintstone
搜索“J Smith 123 Main”应该只返回:
123 Main St SticksVille Joe Smith
Jane Smith
只搜索“J Smith”应该会返回:
123 Main St SticksVille Joe Smith
Jane Smith
456 Another St Sometown Jerry Smith