General table <TEntity>

Trying to use Linq for SQL for a small project that I'm working on at home. I created the context code and all my entity classes using dbmetal.exe (from the DBLinq project) against the local MySQL database.

Everything works fine, but I'm trying to ignore the redundant code, and I am encountering problems trying to do this.

Basically all my objects are of type Table<TEntity>in my context class. For example, I have Table<User>and Table<Calendar>.

While I was architecting various interfaces for the behavior of the repository, I realized that there are some methods that were very redundant with each object. For example, the ID field:

User findById(int id);
Calendar findById(int id);

I designed the tables so that they all have 3 common fields [ID, DATECREATED, DATEUPDATED]. Since these fields are common, I wanted to have common behavior instead of overwriting these methods for each object.

So, I made my repository classes (UserRepository, CalendarRepository) an inheritance of the common Repository class, which is defined like this:

public class Repository<T> : IDisposable, IRepository<T> where T : class
{
    protected MyContext context;

    private DbLinq.Data.Linq.Table<T> currentTable;

    protected Repository() {
        context = new MyContext();

        Type currentType = this.GetType().GetGenericArguments()[0];
        currentTable = //Set currentTable based on currentType. e.g.: currentTable = context.User;
    }        

    #region IRepository<T> Members

    public T findById(int? id)
    {
        return currentTable.SingleOrDefault(d => d.ID == id);
    }

    public T findByDateCreated(DateTime dateCreated)
    {
        return currentTable.SingleOrDefault(d => DateTime.Equals(dateCreated, d.DateCreated));
    }

    public T findByDateUpdated(DateTime dateUpdated)
    {
        return currentTable.SingleOrDefault(d => DateTime.Equals(dateUpdated, d.DateUpdated));
    }

    public T insert(T domainObject)
    {
        currentTable.InsertOnSubmit(domainObject);
        return domainObject;
    }

    public T save(T domainObject)
    {
        context.SubmitChanges();
        return domainObject;
    }

    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        if (context != null)
            context.Dispose();
    }

    #endregion
}

Well, it turns out it's harder than I thought. When I try to install:

currentTable = (Table<T>)context.User;

I get the following error:

Cannot convert type 'DbLinq.Data.Linq.Table<Models.Domain.User>' to 'DbLinq.Data.Linq.Table<T>'

Implicit casting doesn't work either.

Has anyone ever done something like this successfully? It would be very sad if I had all the Repository classes implementing the same findById method with exactly the same code in it ... I am sure there is a way NOT to do this, I just can not find it :)

+3
1

, findById

. .

; . , , , , . ( ) - ( DAL) . DAL, , .

+4

Source: https://habr.com/ru/post/1722227/


All Articles