[英]Finding the “one” in a one-to-many by searching a comma-delimited list
我有两个表, Clients
和Physicians
。 每个Client
都有其医师的主键列表( PhysicianIds
),该列表被展平为逗号分隔的字符串以用于数据库存储( PhysicianStore
)。
我的一种操作方法需要找到医生所属的客户,但是如果不使用.ToList()
评估整个表,就无法找到一种方法。 下面的代码不起作用,因为.Split()
与LINQ-to-Entities不兼容。
我需要为Physician
添加外键吗?
// Data model / DTO
public class ClientModel
{
public List<int> PhysicianIds { get; set; }
public string PhysicianStore
{
get { return string.Join(",", PhysicianIds.ConvertAll<string>(i => i.ToString())); }
set { PhysicianIds = value.Split(',').Select(str => int.Parse(str)).ToList(); }
//set { PhysicianIds = value.Split(',').ToList().ConvertAll<int>(str => int.Parse(str)); }
}
}
public class PhysiciansController
{
// Disposed in full code
private MyDbContext db = new MyDbContext();
public async Task<ActionResult> Details(int? id)
{
if (id == null)
{
return HttpError(HttpStatusCode.BadRequest);
}
PhysicianModel pm = await db.Physicians.FindAsync(id);
if (pm == null)
{
return HttpError(HttpStatusCode.NotFound);
}
// Have to use PhysicianStore here because PhysicianIds is not a column in the DB
return View(new PhysicianDetailsViewModel(pm, db.Clients.Where(c => c.PhysicianStore.Split(',').Contains(pm.Id.ToString()))
.FirstOrDefault()?.Name));
}
}
编辑:根据评论,我确实应该使用导航属性。 我将继续进行下去,并在需要时提出另一个问题。
忽略数据库设计,据我了解,主要问题是LINQ to Entities不支持string.Split
。 但是支持string.Concat
, string.Contains
和ToString
,因此您可以使用以下技巧:
var token = "," + pm.Id.ToString() + ",";
var query = db.Clients
.Where(c => ("," + c.PhysicianStore + ",").Contains(token));
诀窍是用搜索词和目标词都用","
括起来。 这样,它可以正确处理列表的开始,结束和中间元素,并且在"12,21"
内搜索"1"
时不会产生误报。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.