我有一個動態 LINQ 庫,可以為任何IQueryable支持串列和 EntityFramework生成查詢運算式...我想進行一些測驗來檢查物體框架 SQL 提供程式生成的 SQL 查詢。主要問題是我無法使用In-Memory提供程式,因為它沒有向我顯示 SQL 輸出。如何在沒有安裝實際資料庫的情況下撰寫這些測驗?有什么可以使用的包嗎?(我需要測驗 EF SqlServer 和 MySql 提供程式)。
uj5u.com熱心網友回復:
按照檔案中的示例,使用攔截器并抑制實際執行:
public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(
DbCommand command,
CommandEventData eventData,
InterceptionResult<DbDataReader> result,
CancellationToken cancellationToken = default)
{
if (command.CommandText.StartsWith("-- Get_Daily_Message", StringComparison.Ordinal))
{
lock (_lock)
{
if (_message != null
&& DateTime.UtcNow < _queriedAt new TimeSpan(0, 0, 10))
{
command.CommandText = "-- Get_Daily_Message: Skipping DB call; using cache.";
result = InterceptionResult<DbDataReader>.SuppressWithResult(new CachedDailyMessageDataReader(_id, _message));
}
}
}
return new ValueTask<InterceptionResult<DbDataReader>>(result);
}
攔截器 - 執行前
uj5u.com熱心網友回復:
感謝@David Browne - 我最終得到了以下代碼。只是想分享一下,如果將來有人遇到類似的問題。
單元測驗專案鏈接
// interceptors.cs
public class SuppressConnectionInterceptor : DbConnectionInterceptor
{
public override ValueTask<InterceptionResult> ConnectionOpeningAsync(DbConnection connection, ConnectionEventData eventData,
InterceptionResult result,
CancellationToken cancellationToken = new())
{
result = InterceptionResult.Suppress();
return base.ConnectionOpeningAsync(connection, eventData, result, cancellationToken);
}
public override InterceptionResult ConnectionOpening(DbConnection connection, ConnectionEventData eventData, InterceptionResult result)
{
result = InterceptionResult.Suppress();
return base.ConnectionOpening(connection, eventData, result);
}
}
public class SuppressCommandResultInterceptor : DbCommandInterceptor
{
public override InterceptionResult<DbDataReader> ReaderExecuting(
DbCommand command,
CommandEventData eventData,
InterceptionResult<DbDataReader> result)
{
result = InterceptionResult<DbDataReader>.SuppressWithResult(new EmptyMessageDataReader());
return result;
}
public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(
DbCommand command,
CommandEventData eventData,
InterceptionResult<DbDataReader> result,
CancellationToken cancellationToken = default)
{
result = InterceptionResult<DbDataReader>.SuppressWithResult(new EmptyMessageDataReader());
return new ValueTask<InterceptionResult<DbDataReader>>(result);
}
public class EmptyMessageDataReader : DbDataReader
{
private readonly List<User> _users = new List<User>();
public EmptyMessageDataReader()
{
}
public override int FieldCount
=> 0;
public override int RecordsAffected
=> 0;
public override bool HasRows
=> false;
public override bool IsClosed
=> true;
public override int Depth
=> 0;
public override bool Read()
=> false;
public override int GetInt32(int ordinal)
=> 0;
public override bool IsDBNull(int ordinal)
=> false;
public override string GetString(int ordinal)
=> "suppressed message";
public override bool GetBoolean(int ordinal)
=> true;
public override byte GetByte(int ordinal)
=> 0;
public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
=> 0;
public override char GetChar(int ordinal)
=> '\0';
public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
=> 0;
public override string GetDataTypeName(int ordinal)
=> string.Empty;
public override DateTime GetDateTime(int ordinal)
=> DateTime.Now;
public override decimal GetDecimal(int ordinal)
=> 0;
public override double GetDouble(int ordinal)
=> 0;
public override Type GetFieldType(int ordinal)
=> typeof(User);
public override float GetFloat(int ordinal)
=> 0;
public override Guid GetGuid(int ordinal)
=> Guid.Empty;
public override short GetInt16(int ordinal)
=> 0;
public override long GetInt64(int ordinal)
=> 0;
public override string GetName(int ordinal)
=> "";
public override int GetOrdinal(string name)
=> 0;
public override object GetValue(int ordinal)
=> new object();
public override int GetValues(object[] values)
=> 0;
public override object this[int ordinal]
=> new object();
public override object this[string name]
=> new object();
public override bool NextResult()
=> false;
public override IEnumerator GetEnumerator()
=> _users.GetEnumerator();
}
}
// DbContext configuration
public class MyDbContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;");
optionsBuilder.AddInterceptors(new SuppressCommandResultInterceptor());
optionsBuilder.AddInterceptors(new SuppressConnectionInterceptor());
base.OnConfiguring(optionsBuilder);
}
}
// access queryString in unit test
var actual = _dbContext.Users.Where(q => q.Name == "John").ToQueryString();
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/313341.html
標籤:C# sql-server 实体框架 单元测试 实体框架核心
