【发布时间】:2021-02-06 15:40:51
【问题描述】:
我正在尝试找出一种方法,以便能够使用复合主键最小化 EF Core 的“查找”功能。一位工作同事指出了一个似乎确实可行的方向,但我想知道是否有更好的解决方案?
这是我目前所拥有的。
我有一个用于创建模拟数据库集的工厂类。我正在从具有此结构的列表对象创建数据库集;
public int FK { get; set; }
public string SourceId { get; }
public string EntityName { get; set; }
public int? EntityKey { get; set; }
public string IdLong { get; set; }
主键由 FK、EntityName 和 SourceId 组成。
这就是我当前创建 DBSet 的方式
var assocMock = EFCoreFactory.CreateMockDBSet(new List<AData> { obj1, obj2});
// Map the associated data for the EF .Find to work
assocMock.Setup(m => m.Find(It.Is<object[]>(mm =>
mm[0] as int? == obj1.FK &&
mm[1].ToString() == obj1.EntityName &&
mm[2].ToString() == obj1.SourceId
))).Returns(obj1);
assocMock.Setup(m => m.Find(It.Is<object[]>(mm =>
mm[0] as int? == obj2.FK &&
mm[1].ToString() == obj2.EntityName &&
mm[2].ToString() == obj2.SourceId
))).Returns(obj2);
EFCoreFactory.CreateMockSet<AData>(context, assocMock.Object);
有人可以提出更好或更通用的方法吗?
UPDATE 基于下面 Shafiq 提供的链接,这是我的最新尝试,我认为它更通用,不需要我映射每个单独的对象。有人能看出这种方法有什么缺陷吗?
assocMock.Setup(m => m.Find(It.IsAny<object[]>()))
.Returns<object[]>(ad => assocDataList.FirstOrDefault(d => d.FK == (int)ad[0] &&
d.EntityName == ad[1].ToString() &&
d.SourceId == ad[2].ToString()))
【问题讨论】:
-
这篇文章有帮助吗? stackoverflow.com/a/40956071/1718312
-
您可能还想考虑通过 Fluent API 添加密钥,如此处配置主密钥部分的末尾所示:docs.microsoft.com/en-us/ef/core/modeling/…
-
内存提供程序不起作用吗?
-
到目前为止的建议虽然很有帮助,但遗憾的是并没有完全达到我的预期目标,但谢谢。 Shafiq 提供的链接很有帮助,我已经为实体指定了复合键,但为简洁起见,在我的示例中省略了。不幸的是,rgvlee 内存提供程序不能在这种特殊情况下使用。
标签: entity-framework unit-testing entity-framework-core moq