簡體   English   中英

在 sql server json 列中搜索並使用實體框架核心使用它

[英]Searching in sql server json column and consume it using entity framework core

簡而言之,我有一個這樣的模型。

public class User : IEntity
{
    public int Id { get; set; }
    public string Properties { get; set; }
    public DateTime? CreatedAt { get; set; }
    public DateTime? UpdatedAt { get; set; }
    [NotMapped]
    public UserDTO _Properties
    {
        get
        {
            return Properties == null ? null : JsonConvert.DeserializeObject<UserDTO>(Properties);
        }
        set
        {
            Properties = JsonConvert.SerializeObject(value);
        }
    }
}

我將 json 數據存儲在屬性列中,那部分沒問題,然后我有一個查詢,我需要按名稱或電子郵件搜索,所以我有一個存儲庫模式和

alter procedure [dbo].[spSearchUsers]
@term nvarchar(max) AS BEGIN
select Id, JSON_VALUE(Properties, '$.FirstName') as FirstName,
    JSON_VALUE(Properties, '$.LastName') as LastName, 
    JSON_VALUE(Properties, '$.Email') as Email,
    JSON_VALUE(Properties, '$.Role') As [Role],
    JSON_VALUE(Properties, '$.ProgramInformation') as ProgramInformation,
    JSON_VALUE(Properties, '$.CertsAndCredentials') as CertsAndCredentials,
    JSON_VALUE(Properties, '$.Phone') as Phone,
    JSON_VALUE(Properties, '$.LogoUrl') as LogoUrl,
    JSON_VALUE(Properties, '$.ProfessionalPic') as ProfessionalPic,
    JSON_VALUE(Properties, '$.Biography') as Biography,
    CreatedAt, UpdatedAt
from Users
where CONCAT(JSON_VALUE(Properties, '$.FirstName'),' ',JSON_VALUE(Properties, '$.LastName')) like '%'+ @term +'%' 
    or JSON_VALUE(Properties, '$.Email') like '%'+ @term +'%'
    and JSON_VALUE(Properties, '$.IsActive') = 'true'
    and JSON_VALUE(Properties, '$.IsLockedOut') = 'false'
    and JSON_VALUE(Properties, '$.IsVerified') = 'true' END

當我在 sql server management studio 中執行存儲過程時,我得到的信息是正確的:

exec spSearchUsers 'Raul'

我得到這個結果:

1 Raul Alejandro Baez Camarillo raul.baez.camarillo@gmail.com 0 NULL NULL NULL NULL NULL NULL NULL 2021-11-16 03:08:09.6630000 2021-11-16 03:08:09.6630000

所以現在我想在我的控制器中使用那個存儲過程,我使用 Repository 模式,我已經嘗試過像這樣使用 context.Model.FromSqlRaw。

var result = await _context.Users.FromSqlRaw("EXEC dbo.spSearchUsers {0}", term).ToListAsync()

但是當我執行它時,我收到了這個錯誤:

System.InvalidOperationException:“FromSql”操作的結果中不存在所需的“Properties”列。 在 Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable 1.BuildIndexMap(IReadOnlyList 1 columnNames, DbDataReader dataReader) 在 Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable 1.AsyncEnumerator.InitializeReaderAsync(DbContext _, Boolean result, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func BooleanCancellationToken) Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable 1.BuildIndexMap(IReadOnlyList 1 columnNames, DbDataReader dataReader) 1.AsyncEnumerator.InitializeReaderAsync(DbContext _, Boolean result, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func 4 operation, Func 4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable 1.AsyncEnumerator.MoveNextAsync() 在 Microsoft。 EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable 1 source, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable令牌1 source, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable 1 源,CancellationToken 取消令牌)在 AcadminRest.Controllers.UsersController.Search(字符串術語)中 D:\\Projects\\Accomplishment\\AcadminRest\\AcadminRest\\Controllers\\UsersController.cs:Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) 的第 71 行.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)

有人可以幫我得到這個嗎? 提前致謝。

好吧 - 你可以使用價值轉換:

https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions?tabs=data-annotations#composite-value-objects

另一種選擇是為該特定查詢創建一個無鍵實體:

https://docs.microsoft.com/en-us/ef/core/modeling/keyless-entity-types?tabs=data-annotations

編輯:這里有一些關於如何設置無鑰匙實體的信息。 https://stackoverflow.com/a/69924584/4122889

sommmen 提供的選項是我也會提供的選項。 特別是 - 如果您根本不依賴於您的程序。

這兩個選項都為您在存儲庫中提供了一種更簡單的查詢方法。 就個人而言——我會選擇價值轉換,但......這里有更詳細的兩種選擇。

價值轉換:您可能想要使用您的UserDTO並實際映射它。 您的模型如下所示:

public class User : IEntity
{
    public int Id { get; set; }
    public UserDTO Properties { get; set; }
    public DateTime? CreatedAt { get; set; }
    public DateTime? UpdatedAt { get; set; }
}

不需要額外的財產。 然后您的數據庫上下文將被更新以使用Properties的轉換:

// somewhere within OnModelCreating
modelBuilder.Entity<User>(entity =>
{
    entity.Property(r => r.Properties)
        .HasConversion(
            v => JsonConvert.SerializeObject(v),
            v => JsonConvert.DeserializeObject<UserDTO>(v)
        );
});

現在在您的存儲庫中,您可以使用 linq 在您的Users上進行搜索。

var result = await _context.Users
    .Where(u => u.Properties.FirstName.Contains(term) ||
                u.Properties.LastName.Contains(term) || 
                u.Properties.Email.Contains(term))
    .Where(u => u.IsActive && !u.IsLockedOut && u.IsVerified).ToListAsync();

- 或者 -

另一個選項(但與無鍵實體略有不同) - 如果您想使用您的程序中已有的查詢。
使用您的查詢創建一個視圖 ( UserDTO_Properties ), UserDTO_Properties連接第一個/最后一個字段,然后創建一個與您的視圖一起使用的無鍵實體。

您將使用UserDTO並創建無鍵實體以映射到您的視圖。 在您的數據庫上下文中:

    // context prop for dbset
    DbSet<UserDTO> UserDTOs { get; set; }

    // and then somewhere in OnModelCreating
    modelBuilder.Entity<UserDTO>(entity =>
    {
        entity.ToTable("UserDTO_Properties");
        entity.HasNoKey();
    }

現在一個類似的查詢來獲得你的結果:

var result = await _context.UserDTOs
    .Where(u => u.FirstName.Contains(term) ||
                u.LastName.Contains(term) || 
                u.Email.Contains(term)).ToListAsync();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM