在存储库模式中通过 TKey 查找实体<T, TKey>

Find entity by TKey in Repository Pattern<T, TKey>

使用 Repository Pattern,我试图通过 TKey 找到一个实体。我正在尝试找到将 TKeyint

进行比较的方法

实施

public interface IRepository<T, TKey>
{
    T GetById(TKey id);
}

public class Repository<T, TKey> : IRepository<T, TKey> where T : class, IEntity<TKey>
{
    private List<T> _context;

    public Repository(List<T> context)
    {
        _context = context;
    }

    public T GetById(TKey id)
    {
        return _context.Single(m => m.Id == (TKey)id);
    }
}

此处,为TKey

传递int
public interface IEntity<TKey>
{
    TKey Id { get; set; }
}

public class TestEntity : IEntity<int>
{
    public int Id { get; set; }

    public string EntityName { get; set; }
}

最后,测试客户端

var list = new List<TestEntity>();

list.Add(new TestEntity{ Id = 1 , EntityName = "aaa" });
list.Add(new TestEntity{ Id = 2 , EntityName = "bbb" });

var repo = new Repository<TestEntity, int>(list);
var item = repo.GetById(1);

Console.WriteLine(item);

我可能没有按照以下方式进行正确的选择,但尝试过 运行 并出现错误。

public T GetById(TKey id)
{
    return _context.Single(m => (object)m.Id == Convert.ChangeType(id, typeof(TKey));
}

[System.InvalidOperationException: Sequence contains no matching element]

如何在不将参数从 TKey id 更改为 Expression<Func<T, bool>> predicate

的情况下使用相同的方法实现

您不需要所有的转换,绝对不需要字符串转换,因为首先 TKey == TKey,其次,并非所有底层商店都可以应用这些转换。

您需要研究初始代码给出的实际编译器错误:

CS0019: Operator == cannot be applied to operands of type TKey and TKey

为了让 C# 知道它可以比较两个 TKey,您需要将 TKey 约束为 IEquatable<TKey> 并调用 .Equals():

public class Repository<T, TKey> : IRepository<T, TKey>
    where T : class, IEntity<TKey>
    where TKey : IEquatable<TKey>
{
    private List<T> _context;

    public Repository(List<T> context)
    {
        _context = context;
    }

    public T GetById(TKey id)
    {
        return _context.Single(m => m.Id.Equals(id));
    }
}