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

时间:2014-08-10 13:27:12

标签: c# asp.net-mvc nhibernate

我有以下层次结构:

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))

但是我得到了一个N​​Hibernate异常:

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

1 个答案:

答案 0 :(得分:0)

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

相反,我们应该使用IRepository

的原生呼叫扩展我们的session.Get<T>(key)
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;
}