通用存储库和自定义类型的实体Id

本文关键字:类型 实体 Id 自定义 存储 | 更新日期: 2023-09-27 18:17:23

我有以下层次结构:

public interface IIdentifiable<TKey> where TKey : IEquatable<TKey>
{
     TKey Id { get; set; }
}
public interface IEntity<TKey> : IIdentifiable<TKey> where TKey : IEquatable<TKey>
{
}

//base entity
public class Entity<TKey> : IEntity<TKey> where TKey : IEquatable<TKey>
{
    public virtual TKey Id { get; set; }
}
public class Test1: Entity<long>
{
...
}

这是存储库:

public interface IRepository<T, TKey>
        where T : IEntity<TKey>
        where TKey : IEquatable<TKey>
    {
      ...
    }

这个通用存储库:

public class Repository<T, TKey> : IRepository<T, TKey>
        where T : IEntity<TKey>
        where TKey : IEquatable<TKey>
{
...
}
这是我的通用api控制器:
public class BaseReadController<T, TKey> : ApiController where T : IEntity<TKey> where TKey : IEquatable<TKey>
    {
        private readonly IRepository<T, TKey> _repo;
        public BaseReadController(IRepository<T, TKey> repo)
        {
            _repo = repo;
        }      
        public SingleResult<T> Get([FromODataUri] TKey key)
        {
          var test = _repo.Query().Where(t => t.Id == key);
        }
    }

但是我得到了Cannot apply operator == to operands of type Tkey and TKey

我已经试过了:

var test = _repo.Query().Where(t => t.Id.Equals(key))

但是我得到一个NHibernate异常:

message: "Boolean Equals(Int64)"
stacktrace: "   at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression)
type: "System.NotSupportedException"

通用存储库和自定义类型的实体Id

NHibernate的LINQ提供程序有一些…需要改进的地方。因此,我不建议尝试寻找某种方法,如何用其他东西代替.Query().Where(t => t.Id == key);

相反,我们应该用对session.Get<T>(key) 的本机调用来扩展IRepository
public interface IRepository<T, TKey>
    where T : IEntity<TKey>
    where TKey : IEquatable<TKey>
{
  ...
  Get<T>(TKey key)
}

和实现是这样的:

public class Repository<T, TKey> : IRepository<T, TKey>
        where T : IEntity<TKey>
        where TKey : IEquatable<TKey>
{
...
    public virtual Get<T>(TKey key)
    {
        var session = ... // get current session
        var result = session.Get<T>(key);
        return result;
    }
}

最后在控制器中:

public virtual T Get([FromODataUri] TKey key)
{
    var entity = _repo.Get<T>(key);
    return T;
}