我正在开发一个应用程序,我将记录保存在文本列中,例如
{ 12, 13, 14 }
。当我尝试将数据绑定到字符串属性时,我得到以下结果:
System.Linq.Enumerable+SelectArrayIterator`2[System.String,System.Int32]
下面是我的查询,我需要获取整数列表中的 ID。但正如我们在
IQueryable
中所知,我们无法定义任何拆分或任何方法。
public async Task<BaseResponseModel> GetAnswer(int id = 0)
{
response.SuccessModel();
try
{
var answers = await _context.OfferAnswers
.Where(s => (id != 0 ? s.id == id : true) && s.is_deleted == false && s.is_active == true)
.Join(
_context.OfferQuestions.Where(q => q.is_active == true && q.is_deleted == false),
a => a.question_id,
q => q.id,
(a, q) => new { answer = a, question = q }
)
.Join(
_context.Packages.Where(p => p.is_active == true && p.is_deleted == false),
q => q.question.package_id,
p => p.id,
(q, p) => new { answer = q.answer, question = q.question, package = p }
)
.Select(s => new
{
PackageId = s.question.package_id,
Package = s.package.package_name,
QuestionId = s.answer.question_id,
Question = s.question.question,
AnswerId = s.answer.id,
AddOnIds = s.answer.addon_ids,
Answer = s.answer.answer,
Description = s.answer.description,
url = s.answer.icon,
AnswerType = s.answer.answer_type_id,
Product = s.answer.product_ids == null ? null :
_context.Products
.Join(
_context.PackageDetails
.Where(pd => pd.is_active == true && pd.is_deleted == false && pd.package_id == s.question.package_id),
p => p.id,
pd => pd.product_id,
(p, pd) => new { product = p, productdetail = pd }
)
.Select(p => new
{
ProductId = p.product.id,
ProductName = p.product.product_name
})
.ToList(),
Addon = s.answer.addon_ids == null ? null :
_context.add_Ons
.Join(
_context.PackageDetails
.Where(ad => ad.is_active == true && ad.is_deleted == false && ad.package_id == s.question.package_id),
a => a.id,
ad => ad.add_on_id,
(a, ad) => new { addon = a, addondetail = ad }
)
.Select(a => new AddonDto
{
AddonId = a.addon.id,
AddonName = a.addon.add_on_name,
ListIds = s.answer.addon_ids
})
.ToList()
})
.ToListAsync();
response.Data = id != 0 ? answers.FirstOrDefault() : answers.ToList();
response.ResponseMessage = "Packages fetched successfully.";
}
catch (Exception ex)
{
}
return response;
}
AddOnDto
班级:
public class AddonDto
{
public AddonDto()
{
this.AddonIds = new List<int>();
}
public int AddonId { get; set; }
public string? AddonName { get; set; }
public List<int> AddonIds { get; set; }
private string _listIds; // backing field for ListIds
public string ListIds {get; set;}
}
这是表格的屏幕截图:
公共类AddonDto { 公共 int AddonId { 获取;放; } 公共字符串?插件名称 { 获取;放; } 私有字符串_listIds; 公共字符串 ListId { 获取=>_listIds; 放 { _listIds = 值; _addonIds = null; }
}
private List<int>? _addonIds = null;
[NotMapped] // If this is an entity class so EF doesn't try and map this property.
public IReadOnlyCollection<int> AddonIds
{
get
{
return _addonIds ??= new List<int>(ListIds
.Split(',', StringSplitOptions.RemoveEmptyEntries)
.Select(x => int.Parse(x));
}
}
}如果您想更改关联的附加组件,请公开“AddAddon(int)”和“RemoveAddon(int)”等操作方法,它们可以向支持集合添加或删除所需的 Id 并更新 ListIds 字符串。请注意,如果 ListIds 字符串允许设置器,则应删除后备集合以确保重新计算它以反映当前字符串。
当涉及实体内的分隔字符串时,我建议使用有边缘的分隔符,其中每个条目的两侧总是可以找到分隔符。例如,使用管道分隔符而不是“1,2,3,4”,您将得到“|1|2|3|4|”上述基于拆分的逻辑适用于任一分隔符模式/字符,但在 Linq 中高效查询数据时,您不能在 Linq 查询中使用“AddonIds”(
List<int>
),您需要对字符串支持执行
Contains
场地。使用边缘分隔符,您可以执行类似
.Where(x => x.ListIds.Contains($"|{addonId}|"))
的操作来查找包含分隔的 addonId 值的条目。使用逗号分隔的列表,如果您执行
.Where(x => x.ListIds.Contains(addonId))
搜索 Id #1 将找到“1”、“10”、“11”、“21”,并且不能依赖
.Where(x => x.ListIds.Contains($",{addonId},"))
,因为这不会找到条目其中“1”是第一个或最后一个条目。使用边缘分隔符,它将专门查找包含“|1|”的条目“1”是否在正面、背面或中间,并且仅匹配找到“1”的情况,而不匹配“|10|”的情况例如。