Mock带Where条件的SqlQuery返回全部数据,如何按属性过滤?
问题分析与解决
首先你的SQL语句存在语法错误,正确写法应该是:
var myObjects = _context .Set<myObject>() .SqlQuery("select * from myObject where id = '1'") .AsNoTracking() .ToList();
但这不是Mock场景下返回全部数据的核心原因——因为你是在Mock Entity Framework的SqlQuery方法,默认的Mock实现不会解析你传入的SQL语句,不管你写什么Where条件,都会直接返回预设的完整数据集。
要实现根据属性过滤的效果,你需要在MockSqlQuery时,添加逻辑来解析传入的SQL(或者提取条件参数),然后对预设的数据集进行过滤:
举个示例(以Moq为例):
// 预设的测试数据 var testData = new List<myObject> { new myObject { Id = "1", Name = "Test1" }, new myObject { Id = "2", Name = "Test2" } }.AsQueryable(); // Mock DbSet var mockSet = new Mock<DbSet<myObject>>(); // 重写SqlQuery的Mock逻辑,解析SQL中的id条件 mockSet.Setup(m => m.SqlQuery(It.IsAny<string>(), It.IsAny<object[]>())) .Returns<string, object[]>((sql, args) => { // 简单提取id条件(实际场景可以用正则或SQL解析库处理) if (sql.Contains("id = '1'")) { return testData.Where(o => o.Id == "1").AsDbQuery(); } // 其他条件或默认返回全部 return testData.AsDbQuery(); }); // 将Mock的DbSet注入到Context var mockContext = new Mock<MyDbContext>(); mockContext.Setup(c => c.Set<myObject>()).Returns(mockSet.Object);
关键说明:
- 原生EF的
SqlQuery会把SQL发送给数据库执行过滤,但Mock环境下不会真的连接数据库,所以需要自己处理条件过滤逻辑 - 简单场景可以通过字符串匹配提取条件,复杂场景建议使用轻量SQL解析库来解析WHERE子句,再动态过滤数据集
- 如果你只是想通过属性过滤而非写原生SQL,Mock场景下直接用
WhereLINQ方法会更简单,不需要依赖SqlQuery
内容的提问来源于stack exchange,提问作者syafi
相关产品推荐
相关产品推荐

