DB First with Base Entity Interface
Asked Answered
I

1

6

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?

Implicit answered 1/3, 2017 at 10:17 Comment(1)
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 https://mcmap.net/q/654214/-adding-an-interface-to-a-partial-classPreference
P
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.

Preference answered 1/3, 2017 at 10:30 Comment(3)
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?Implicit
@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 modelPreference
@akhil If this helped, please consider up voting or marking the green check box. If you need further clarification I can try updating the answerPreference

© 2022 - 2024 — McMap. All rights reserved.