LINQ到实体——动态生成where谓词
本文关键字:where 谓词 动态 实体 LINQ | 更新日期: 2023-09-27 18:17:16
我有这个:
public void AssertReadWorks<T>(
IRepository<T> repository,
T entity,
Expression<Func<T, T, bool>> keyComparer) where T : class
{
entity = repository.GetAll().Single(x => x.Id == entity.Id);
}
[TestMethod]
public void ReadTest_DataFieldGroup()
{
AssertReadWorks(
_unitOfWork.DataFieldSetRepository,
new DataFieldSet { Label = "test", Title = "test" },
(a, b) => a.Id == b.Id);
}
不能编译,因为不知道T有Id属性。请注意,目前没有使用keyComparer
参数。我想使用keyComparer参数(或其他适当的参数)来动态生成Single()
的谓词:
Expression<Func<T, bool>> keyComparingPredicate =
x => a predicate that compares the key of x with the key of `entity`;
entity = repository.GetAll().Single(keyComparingPredicate);
关键是不是所有的t都有Id属性,有些会有不同的名字,有些会有组合键。原来的AssertReadWorks()
工作良好,如果它不是通用的。问题只是在一般情况下动态地构建谓词。如果可以用不同于keyComparer参数的东西来完成,我同意。
任何想法?:)
检查一下,是否适合你
public T AssertReadWorks<T>(
IRepository<T> repository,
Func<T, bool> keyComparer)
{
return repository.GetAll().Single(keyComparer);
}
使用[TestMethod]
public void TestInt()
{
var repository = new Repository<int>( new[] {1, 2, 3} );
var intEntity = 3;
AssertReadWorks(repository, e => e == intEntity);
}
[TestMethod]
public void TestString()
{
var repository = new Repository<string>(new[] { "a", "b", "c" });
var stringEntity = "A";
AssertReadWorks(repository, e => string.Equals(e, stringEntity, StringComparison.OrdinalIgnoreCase));
}
[TestMethod]
public void TestThread()
{
var threadEntity = new Thread(() => { });
var repository = new Repository<Thread>(new[] { threadEntity, new Thread(() => { }), new Thread(() => { }) });
AssertReadWorks(repository, e => e.ManagedThreadId == threadEntity.ManagedThreadId);
}
编辑:评论回复:
public void AssertReadWorks<T>(
IRepository<T> repository,
ref T entity,
Func<T, T, bool> keyComparer)
{
var localEntity = entity;
entity = repository.GetAll().Single(e => keyComparer(e, localEntity));
}
如果我错了,请纠正我,但这个函数的全部意义是检查相等性吗?要在一般意义上做到这一点,您可以使用等价接口。这样,您的对象就知道如何将自己与同一对象进行比较。这将减少代码重用,并有助于避免在多个地方创建相同的表达式。
那么你的类应该是这样的:
public class DataFieldSet : IEquatable<DataFieldSet>
{
public int Id { get; set; }
public bool Equals(DataFieldSet other)
{
return other != null && this.Id == other.Id;
}
}
和Assert函数
public void AssertReadWorks<T>(
IRepository<T> repository,
T entity) where T : IEquatable<T>
{
entity = repository.GetAll().Single(x => entity.Equals(x);
}