5

Environment:

I am working in DB First Approach. I am having 3 tables in my database. All these tables have status field to indicate the record status. This is an integer field.

Scenario:

I created model diagram from this table using db first approach. Then i created a generic repository Interface and class for CRUD operations.

The following is interface;

public interface IGenericRepository<T> where T : class
{

    IQueryable<T> GetAll();
    Task<T> GetAsync(int id);
    void Add(T entity);
    void Delete(T entity);
    void Edit(T entity);
    Task<bool> SaveAsync();
}

The following is the generic Repository class

    public abstract class GenericRepository<C, T> :
        IGenericRepository<T> where T : class
                              where C : MyDBContext, new()
    {
    public virtual IQueryable<T> GetAll()
    {
        IQueryable<T> query = _entities.Set<T>();
        return query;
    }
//Removed other methods for clarity
}

Requirement:

In GetAll method, I need to check the status field and return only value = 1

Current Solution I have:

As this is generic repository, I can't access field in the methods. We can create a base Interface with Status field, then inherit it in generic repository and can use this field in the method.

Changes like below;

    public interface IGenericRepository<T> where T : class, IBaseEntity
    {
   //Methods removed for clarity
    }

    public abstract class GenericRepository<C, T> :
        IGenericRepository<T> where T : class, IBaseEntity
                              where C : MyDBContext, new()
    {
        public virtual IQueryable<T> GetAll()
        {
            IQueryable<T> query = _entities.Set<T>().Where(x => x.Status== 1);
            return query;
        }
}

Problems:

To work this, we need to inherit base interface to all my models. As the model is generated from Database, I manually added IBaseEntity into each model in the edmx tt file.

If my databse have any changes and i updated the diagram again, the manaully added interface is removed.

So any other alternative methods in DBFirst or my solution is wrong in DB First?

Akhil
  • 1,918
  • 5
  • 30
  • 74
  • Those tools implement `partial` classes. Open up a new cs file and add another `partial` class definition for your class (with the same name), and with the interface implemented on it. Partial classes don't need the interface designated on all pieces. See here http://stackoverflow.com/a/20508313/491907 – pinkfloydx33 Mar 01 '17 at 10:24

1 Answers1

4

The classes that are generated by db-first tools usually have the partial specifier. This means that you can "extend" the definition by adding another partial class definition for the same class in a different file (that you control and won't be overwritten). Interfaces can be implemented on separate parts of the partial class.

The generated file:

public partial class MyEntity {} 

Your separate file:

public partial class MyEntity : IMyInterface {} 

For more information you can see this question or the MSDN article on partial classes and methods.

Community
  • 1
  • 1
pinkfloydx33
  • 11,863
  • 3
  • 46
  • 63
  • great I got it. But here i have a confusion. It may be silly. If i delete the table and update the model, i need to manually delete this extended partial class. correct? – Akhil Mar 02 '17 at 04:20
  • @akhil If you remove the table completely, yes. Otherwise no. You can put other methods and non-db related properties in the other file and this way they don't get overwritten everytime you refresh your model – pinkfloydx33 Mar 02 '17 at 11:13
  • @akhil If this helped, please consider up voting or marking the green check box. If you need further clarification I can try updating the answer – pinkfloydx33 Mar 02 '17 at 11:14