C# 如何实现泛型GetById(),其中Id可以是各种类型

C# 如何实现泛型GetById(),其中Id可以是各种类型,c#,asp.net-mvc,generics,repository-pattern,C#,Asp.net Mvc,Generics,Repository Pattern,我正在尝试实现一个通用的GetById(tid)方法,它将满足可能具有不同id类型的类型。在我的示例中,有一个实体的ID类型为int,另一个类型为string public interface IEntity<TId> where TId : class { TId Id { get; set; } } 但是,我不断遇到错误,我不知道为什么: 类型“int”必须是引用类型,才能将其用作方法IEntity的泛型类型中的参数“TId” 实体接口: public class En

我正在尝试实现一个通用的
GetById(tid)
方法,它将满足可能具有不同id类型的类型。在我的示例中,有一个实体的ID类型为
int
,另一个类型为
string

public interface IEntity<TId> where TId : class
{
    TId Id { get; set; }
}
但是,我不断遇到错误,我不知道为什么:

类型“int”必须是引用类型,才能将其用作方法IEntity的泛型类型中的参数“TId”

实体接口:

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

    // Other model properties...
}

public class EntityTwo : IEntity<string>
{
    public string Id { get; set; }

    // Other model properties...
}
public interface IRepository<TEntity, TId> where TEntity : class, IEntity<TId>
{
    TEntity GetById(TId id);
}
public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId>
    where TEntity : class, IEntity<TId>
    where TId : class
{
    // Context setup...

    public virtual TEntity GetById(TId id)
    {
        return context.Set<TEntity>().SingleOrDefault(x => x.Id == id);
    }
}
 public class EntityOneRepository : Repository<EntityOne, int>
    {
        // Initialise...
    }

    public class EntityTwoRepository : Repository<EntityTwo, string>
    {
        // Initialise...
    }
为了满足我的域模型,它可以具有类型为
int
string
的Id

public interface IEntity<TId> where TId : class
{
    TId Id { get; set; }
}
公共接口,其中TId:class
{
TId Id{get;set;}
}
实体实现:

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

    // Other model properties...
}

public class EntityTwo : IEntity<string>
{
    public string Id { get; set; }

    // Other model properties...
}
public interface IRepository<TEntity, TId> where TEntity : class, IEntity<TId>
{
    TEntity GetById(TId id);
}
public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId>
    where TEntity : class, IEntity<TId>
    where TId : class
{
    // Context setup...

    public virtual TEntity GetById(TId id)
    {
        return context.Set<TEntity>().SingleOrDefault(x => x.Id == id);
    }
}
 public class EntityOneRepository : Repository<EntityOne, int>
    {
        // Initialise...
    }

    public class EntityTwoRepository : Repository<EntityTwo, string>
    {
        // Initialise...
    }
公共类EntityOne:EntityOne
{
公共int Id{get;set;}
//其他模型属性。。。
}
公共类实体2:实体
{
公共字符串Id{get;set;}
//其他模型属性。。。
}
通用存储库接口:

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

    // Other model properties...
}

public class EntityTwo : IEntity<string>
{
    public string Id { get; set; }

    // Other model properties...
}
public interface IRepository<TEntity, TId> where TEntity : class, IEntity<TId>
{
    TEntity GetById(TId id);
}
public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId>
    where TEntity : class, IEntity<TId>
    where TId : class
{
    // Context setup...

    public virtual TEntity GetById(TId id)
    {
        return context.Set<TEntity>().SingleOrDefault(x => x.Id == id);
    }
}
 public class EntityOneRepository : Repository<EntityOne, int>
    {
        // Initialise...
    }

    public class EntityTwoRepository : Repository<EntityTwo, string>
    {
        // Initialise...
    }
公共接口假定,其中tenty:class,ienty
{
tenty-GetById(TId-id);
}
通用存储库实现:

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

    // Other model properties...
}

public class EntityTwo : IEntity<string>
{
    public string Id { get; set; }

    // Other model properties...
}
public interface IRepository<TEntity, TId> where TEntity : class, IEntity<TId>
{
    TEntity GetById(TId id);
}
public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId>
    where TEntity : class, IEntity<TId>
    where TId : class
{
    // Context setup...

    public virtual TEntity GetById(TId id)
    {
        return context.Set<TEntity>().SingleOrDefault(x => x.Id == id);
    }
}
 public class EntityOneRepository : Repository<EntityOne, int>
    {
        // Initialise...
    }

    public class EntityTwoRepository : Repository<EntityTwo, string>
    {
        // Initialise...
    }
公共抽象类存储库:IRepository
其中tenty:类,tenty
TId:class在哪里
{
//上下文设置。。。
公共虚拟用户id(TId id)
{
返回context.Set().SingleOrDefault(x=>x.Id==Id);
}
}
存储库实现:

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

    // Other model properties...
}

public class EntityTwo : IEntity<string>
{
    public string Id { get; set; }

    // Other model properties...
}
public interface IRepository<TEntity, TId> where TEntity : class, IEntity<TId>
{
    TEntity GetById(TId id);
}
public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId>
    where TEntity : class, IEntity<TId>
    where TId : class
{
    // Context setup...

    public virtual TEntity GetById(TId id)
    {
        return context.Set<TEntity>().SingleOrDefault(x => x.Id == id);
    }
}
 public class EntityOneRepository : Repository<EntityOne, int>
    {
        // Initialise...
    }

    public class EntityTwoRepository : Repository<EntityTwo, string>
    {
        // Initialise...
    }
公共类EntityOneRepository:存储库
{
//初始化。。。
}
公共类EntityTwoRepository:存储库
{
//初始化。。。
}

您应该从
存储库
类中删除对TId的约束

public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId>
where TEntity : class, IEntity<TId>
{
    public virtual TEntity GetById(TId id)
    {
        return context.Set<TEntity>().Find(id);
    }
}
公共抽象类存储库:IRepository
其中tenty:类,tenty
{
公共虚拟用户id(TId id)
{
返回context.Set().Find(id);
}
}
对您的问题:
我正在尝试实现一个通用的GetById(tid)方法,该方法将满足可能具有不同id类型的类型。在我的示例中,有一个实体的ID为int类型,另一个为string类型。

public-virtualtenty-GetById(TId-id)
{
返回context.Set().SingleOrDefault(x=>x.Id==Id);
}
对于泛型参数,只需创建一个像上面那样的泛型方法

公共接口,其中TId:class
public interface IEntity<TId> where TId : class
{
    TId Id { get; set; }
}
{ TId Id{get;set;} }
where-TId:class
约束要求每个实现都有一个从对象派生的Id,而对于int等值类型,该Id不是真的

这就是错误消息告诉您的:
类型“int”必须是引用类型,才能将其用作方法IEntity的泛型类型中的参数“TId”


只需从
IEntity

中删除约束
where TId:class
,为什么要将
TId
限制为
class
类型?这对
int
不起作用(错误消息非常清楚)
class
在泛型约束中表示“引用类型”。此建议解决了引用类型错误,但是,我现在得到一个
运算符==无法应用于TId类型的操作数,并且在尝试按id执行匹配时出现了一个
错误。如果我使用
。Find(id),它会正常工作
而不是
.SingleOrDefault(x=>x.Id==Id)
。不过,我希望它在这个方法后面做的是完全相同的事情,所以不确定为什么
.Find()
是有效的。对于
.SingleOrDefault(x=>x.Id==Id)
错误,您也可以使用
.SingleOrDefault(x=>x.Id.Equals(Id))