Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
547 views
in Technique[技术] by (71.8m points)

c# - How to implement generic GetById() where Id can be of various types

I am trying to implement a generic GetById(T id) method which will cater for types which may have differing ID types. In my example, I have an entity which has an ID of type int, and one of type string.

However, I keep getting an error and I have no idea why:

The type 'int' must be a reference type in order to use it as parameter 'TId' in the generic type of method IEntity

Entity Interface:

To cater for my domain models which can have Id's of type int or string.

public interface IEntity<TId> where TId : class
{
    TId Id { get; set; }
}

Entity Implementations:

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...
}

Generic Repository Interface:

public interface IRepository<TEntity, TId> where TEntity : class, IEntity<TId>
{
    TEntity GetById(TId id);
}

Generic Repository Implementation:

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

Repository Implementations:

 public class EntityOneRepository : Repository<EntityOne, int>
    {
        // Initialise...
    }

    public class EntityTwoRepository : Repository<EntityTwo, string>
    {
        // Initialise...
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should remove the constraint on TId from your Repository class

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...