开发者

EntityFramework repository template - how to write GetByID lambda within a template class?

开发者 https://www.devze.com 2023-01-01 08:59 出处:网络
I am trying to write a generic one-size-fits-most repository pattern template class for an Entity Framework-based project I\'m currently working on. The (heavily simplified) interface is:

I am trying to write a generic one-size-fits-most repository pattern template class for an Entity Framework-based project I'm currently working on. The (heavily simplified) interface is:

internal interface IRepository<T> where T : class
{
  T GetByID(int id);
  IEnumerable<T> GetAll();
  IEnumerable<T> Query(Func<T, bool> filter);
}

GetByID is proving to be the killer. In the implementation:

public class Repository<T> : IRepo开发者_运维知识库sitory<T>,IUnitOfWork<T> where T : class
{
  // etc...
  public T GetByID(int id)
  {
    return this.ObjectSet.Single<T>(t=>t.ID == id);
  }

t=>t.ID == id is the particular bit I'm struggling with. Is it even possible to write lambda functions like that within template classes where no class-specific information is going to be available?


I've defined a interface:

public interface IIdEntity
{
    long Id { get; set; }
}


And modified the t4 template which generates my POCO classes so that every class must implement the public interface IIdEntity interface.

Like this:

using System.Diagnostics.CodeAnalysis;
public partial class User : IIdEntity
{
    public virtual long Id
    {
        get;
        set;
    }

With this modification I can write a generic GetById(long id) like:

public T GetById(long id)
{
    return Single(e => e.Id == id);
}

The IRepository is defined as follows:

/// <summary>
/// Abstract Base class which implements IDataRepository interface.
/// </summary>
/// <typeparam name="T">A POCO entity</typeparam>
public abstract class DataRepository<T> : IDataRepository<T>
    where T : class, IIdEntity
{


You could just create a small interface containing the Id-property and have T be constrained to types that implement it.

EDIT: Based on the comment, if you accept the fact that the compiler wont be helping you ensure that the Id property actually exists you might be able to do something like this:

public class Repo<T> where T : class
{
    private IEnumerable<T> All()
    {
        throw new NotImplementedException();
    }

    private bool FilterOnId(dynamic input, int id)
    {
        return input.Id == id;
    }

    public T GetById(int id)
    {
        return this.All().Single(t => FilterOnId(t, id));
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号