linq 的值对象不能包含方法

问题描述 投票:0回答:1

我正在将 EF Core 8 与 Oracle 数据库结合使用。

我正在尝试选择列中包含值的数据。 SQL 语句如下:

SELECT * 
FROM TASKS 
WHERE NAME LIKE "%Task%"

我有以下 linq 代码(

Name
是字符串类型的
ValueObject
):

 List<TaskEntity> tasks = await _dbSet.Where(x => x.Name.Value.Contains("Task"))
                                      .ToListAsync();

还有实体

public partial class TaskEntity 
{
    public DatabaseTableId Id { get; set; }
    public Name Name { get; set; }
}

但我收到此错误:

System.InvalidOperationException:'LINQ 表达式
'DbSet()
.Where(t => t.Name.Value.Contains("Task"))' 无法翻译。

模型构建者:

modelBuilder.Entity<TaskEntity>(entity =>
{
    entity.HasKey(e => e.Id);

    entity.ToTable("TASKS");

    entity.Property(e => e.Id)
        .HasConversion<DatabaseTableIdConverter>()
        .ValueGeneratedOnAdd()
        .HasColumnType("NUMBER")
        .HasColumnName("ID");
    entity.Property(e => e.Name)
        .HasConversion<NameConverter>()
        .HasMaxLength(50)
        .IsUnicode(false)
        .HasColumnName("NAME");
});

姓名 VO(简体):

public class Name
{
    public string Value { get; }

    public Name(string value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentNullException(nameof(Name), "Name cannot be null or empty.");
        }

        Value = value;
    }
}

名称转换器:

public class NameConverter : ValueConverter<Name, string>
{
    /// <summary>
    /// Converts a <see cref="Name"/> to a <see cref="string"/> value to use it in EF
    /// </summary>
    public NameConverter() : base
    (
        Name => Name.Value,
        value => new Name(value))
    { }
}

我已经尝试了一切,使用

EF.Function.Like
... 和
FromSqlRaw
的值对象中的 contains 方法确实有效,但我需要
IQueryable

.net entity-framework linq .net-8.0 entity-framework-8
1个回答
0
投票

您可以通过添加隐式转换运算符来增强您的

Name
类:

public class Name
{
    public string Value { get; }

    public Name(string value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentNullException(nameof(Name), "Name cannot be null or empty.");
        }

        Value = value;
    }

    public static implicit operator string(Name name) => name.Value;
    public static implicit operator Name(string value) => new Name(value);
}

这允许您在查询时使用显式转换:

List<TaskEntity> tasks = await _dbSet
  .Where(x => ((string)x.Name).Contains("Task"))
  .ToListAsync();

已使用 EF Core 8 进行测试。

© www.soinside.com 2019 - 2024. All rights reserved.