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