Linq-запрос через определенное свойство преобразования значения - PullRequest
0 голосов
/ 30 марта 2020

Извиняюсь, если заголовок сбивает с толку.

У меня есть объект User, в котором хранится список внешних идентификаторов.

public class User
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public int[] ExternalIds { get; set; }
}

Я использую Преобразователи значений EF Core чтобы преобразовать эти значения в строку через запятую.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var valueComparer = new ValueComparer<int[]>(
        (c1, c2) => c1.SequenceEqual(c2),
        c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
        c => c.ToArray());

    modelBuilder
        .Entity<User>()
        .Property(user => user.ExternalIds)
        .HasConversion(
            externalIds => string.Join(',', externalIds),
            dbExternalIds => dbExternalIds.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray())
        .Metadata
        .SetValueComparer(valueComparer);
}

Теперь у меня проблема с запросом через ExternalIds. Если я запускаю следующее, я получаю обратно правильно построенные User объекты

using (var context = new PersonDbContext())
{
    var allUsers = context.Users.ToList();
}

Однако, если я пытаюсь выполнить запрос, используя ExternalIds У меня возникают проблемы

Первая попытка была простой запрос, подобный следующему:

var user = 
    context.Users.FirstOrDefault(u => u.ExternalIds.Contains(externalId));

Но это не возвращает никакого результата, что неудивительно, так как он генерируется SQL

SELECT TOP(1) [u].[Id], [u].[ExternalIds], [u].[Name]
FROM [Users] AS [u]
WHERE CAST(1 AS bit) = CAST(0 AS bit)

Я искал Like запросов через EF.Functions, но не может его скомпилировать из-за того, что ExternalIds не является строкой

var user = context.Users
    .FirstOrDefault(u =>
        EF.Functions.Like(u.ExternalIds, "%1%"));

Какой правильный способ запроса через свойство, у которого есть преобразователи значений?

Пока я не Мне не нравится хранить значения в виде строки, разделенной запятыми, вставка ExternalIds в выделенную таблицу звучит как перебор - в нем будут только идентификаторы и ничего больше.

Я использую EF Core 3.1 на. Net Core 3.1.

<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.2" />
...