我最近在使用Microsoft.EntityFrameworkCore.Proxies
时遇到了同样的问题。在我的情况下,我必须比较持久属性并忽略比较其他导航属性。
解决方案是实现接口FluentAssertions.Equivalency.IMemberSelectionRule
来排除不必要的属性。
public class PersistentPropertiesSelectionRule<TEntity> : IMemberSelectionRule
where TEntity : class
{
public PersistentPropertiesSelectionRule(DbContext dbContext) =>
this.dbContext = dbContext;
public bool IncludesMembers => false;
public IEnumerable<SelectedMemberInfo> SelectMembers(
IEnumerable<SelectedMemberInfo> selectedMembers,
IMemberInfo context,
IEquivalencyAssertionOptions config)
{
var dbPropertyNames = dbContext.Model
.FindEntityType(typeof(TEntity))
.GetProperties()
.Select(p => p.Name)
.ToArray();
return selectedMembers.Where(x => dbPropertyNames.Contains(x.Name));
}
public override string ToString() => "Include only persistent properties";
readonly DbContext dbContext;
}
然后编写一个扩展方法可以帮助方便使用,也可以提高可读性。扩展方法可以是以下代码段中的内容。
public static class FluentAssertionExtensions
{
public static EquivalencyAssertionOptions<TEntity> IncludingPersistentProperties<TEntity>(this EquivalencyAssertionOptions<TEntity> options, DbContext dbContext)
where TEntity : class
{
return options.Using(new PersistentPropertiesSelectionRule<TEntity>(dbContext));
}
}
最后你可以像下面这段代码一样在测试中调用扩展方法。
using (var context = DbContextFactory.Create())
{
var myEntitySet = context.MyEntities.ToArray();
myEntitySet.Should().BeEquivalentTo(expectedEntities, options => options
.IncludingPersistentProperties(context)
.Excluding(r => r.MyPrimaryKey));
}
这个实现解决了我的问题,代码看起来整洁清晰。
Equals
,删除它解决了问题。感谢您的回复,但我可以建议您在“升级提示”部分(在“更改BeEquivalentTo”下)添加一个附加的项目符号,以确保任何Equals
实现符合它应该遵循的引用类型值语义原则吗? - NeoIncludingAllRuntimeProperties
或RespectingRuntimeTypes
解决了我的问题。 - Samuel