我用DDD方法开发了一个项目来管理假期。我有两个值对象的名字是HolidayTitle和HolidayDate。现在我想在查询存储库中过滤包含,但我不能。
我在仓库中的代码如下:
public async Task<ListResponse<IList<GetHolidaysByDatesDto>>> GetHolidays(GetHolidaysQuery param)
{
var query = _repository.AsQueryable();
if (param.Date.HasValue)
query = query.Where(x => x.Date == param.Date);
if (!string.IsNullOrEmpty(param.Title))
query = query.Where(x => x.Title.Contains(param.Title));
var pagingData = await query.GetPagingData(param);
query = query.SetPaging(param);
var holidays = await query.ToListAsync();
var mappedResult = _mapper.Map<IList<GetHolidaysByDatesDto>>(holidays);
var finalResult = new ListResponse<IList<GetHolidaysByDatesDto>>()
{
PageCount = pagingData.PageCount,
PageNumber = pagingData.PageNumber,
RowCount = pagingData.RowCount,
Result = mappedResult
};
return finalResult;
}
和HolidayTitle的代码如下
public class HolidayTitle : BaseValueObject<HolidayTitle>
{
public static readonly int minLength = 5;
public static readonly int maxLength = 300;
public string Value { get; private set; }
private HolidayTitle(string value)
{
if (value is null)
throw new NullOrEmptyArgumentException(HolidayErrors.HolidayTitleIsNull);
value = value.Trim();
if (value == string.Empty)
throw new NullOrEmptyArgumentException(HolidayErrors.HolidayTitleIsEmpty);
if (value.Length > maxLength || value.Length < minLength)
throw new RangeLengthArgumentException(HolidayErrors.HolidayTitleLengthIsNotInRangeLength, minLength.ToString(), maxLength.ToString());
Value = value;
}
public bool Contains(string str)
{
return Value.Contains(str);
}
public override bool IsEqual(HolidayTitle otherObject)
{
return Value == otherObject.Value;
}
public override int ObjectGetHashCode()
{
return Value.GetHashCode();
}
public static implicit operator string(HolidayTitle value)
{
return value.Value;
}
public static HolidayTitle GetInstance(string value)
{
return new(value);
}
}
我得到这个错误
System.InvalidOperationException: 'The LINQ expression 'DbSet<Holiday>()
.Where(h => !(h.IsDeleted))
.Where(h => h.Title.Contains(__param_Title_0))' could not be translated. Additional information: Translation of method 'Core.Domain.Holidays.ValueObjects.HolidayTitle.Contains' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
EF无法将其转换为查询。有一种方法可以将整个数据加载到内存中,然后对其进行过滤。
您必须使用下面的,因为query
是IQueryable
:
query.AsEnumerable()
.Where......
不能写
query = query.Where(x => x.Title.Contains(param.Title));
因为EF不知道你的HolidayTitle.Contains
方法
string.Contains
:
query = query.Where(x => x.Title.Value.Contains(param.Title));