[英]How to insert and update SQL Server DateTime in a date column using Entity Framework Core in .NET Core
[英]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.FromSqlQueryingEnumerable1.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.FromSqlQueryingEnumerable1.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, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable
1.AsyncEnumerator.MoveNextAsync() 在 Microsoft。 EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1 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/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.