0

I have a created a Windows application which contains a class library. I want to add an entity framework to the class library, so it can be easy to work with my database file.

I was able to add an entity framework in my application and was able to create a data access layer, but now I want to create a data access layer in the class library. I have searched the internet, but didn't find any help.

Also my dll file is in a different folder. Would this cause a problem?

karel
  • 5,489
  • 46
  • 45
  • 50
Broick
  • 27
  • 1
  • 10
  • Creating an EF model in a library project is no different to doing it in an application project. Once you've done it, they are just classes like any other so you access them like any other classes in a library. What have you done and what exactly happened that makes you think that it works differently? – jmcilhinney Feb 15 '19 at 13:32
  • Possible duplicate of [Entity Framework - layered design - Where to put connectionstring?](https://stackoverflow.com/questions/859709/entity-framework-layered-design-where-to-put-connectionstring) – TGnat Feb 15 '19 at 14:16

1 Answers1

0

You can implement a custom repository in your data layer, and like this is easier to use it.

For example

IRepository.cs

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;

namespace Persistence.Repository
{
    public interface IRepository<T>
    {
    #region IRepository<T> Members
    /// <summary>
    /// Retorna un objeto del tipo AsQueryable
    /// </summary>
    /// <returns></returns>
    IQueryable<T> AsQueryable();

    /// <summary>
    /// Retorna un objeto del tipo AsQueryable y acepta como parámetro las relaciones a incluir
    /// </summary>
    /// <param name="includeProperties"></param>
    /// <returns></returns>
    IEnumerable<T> GetAll(params Expression<Func<T, object>>[] includeProperties);


    IEnumerable<T> ThenInclude(params Expression<Func<T, object>>[] includeProperties);

    /// <summary>
    /// Retorna un objeto del tipo AsQueryable bajo una condición que especifiques como parámetro
    /// </summary>
    /// <param name="where"></param>
    /// <param name="includeProperties"></param>
    /// <returns></returns>
    IEnumerable<T> Find(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties);

    /// <summary>
    /// Retorna una entidad bajo una condición especificada
    /// </summary>
    /// <param name="where"></param>
    /// <param name="includeProperties"></param>
    /// <returns></returns>
    T Single(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties);

    /// <summary>
    /// Retorna una entidad bajo una condición especificada o null sino encontrara registros
    /// </summary>
    /// <param name="where"></param>
    /// <param name="includeProperties"></param>
    /// <returns></returns>
    T SingleOrDefault(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties);

    /// <summary>
    /// Retorna la primera entidad encontrada bajo una condición especificada
    /// </summary>
    /// <param name="where"></param>
    /// <param name="includeProperties"></param>
    /// <returns></returns>
    T First(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties);

    /// <summary>
    /// Retorna la primera entidad encontrada bajo una condición especificada o null sino encontrara registros
    /// </summary>
    /// <param name="where"></param>
    /// <param name="includeProperties"></param>
    /// <returns></returns>
    T FirstOrDefault(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties);

    /// <summary>
    /// Retorna la primera entidad encontrada bajo una condición especificada o new sino encontrara registros
    /// </summary>
    /// <param name="where"></param>
    /// <param name="includeProperties"></param>
    /// <returns></returns>
    T FirstOrNew(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties);


    /// <summary>
    /// Elimina una entidad
    /// </summary>
    /// <param name="entity"></param>
    void Delete(T entity);

    /// <summary>
    /// Elimina varias entidades
    /// </summary>
    /// <param name="entity"></param>
    void DeleteRange(IEnumerable<T> entities);

    /// <summary>
    /// Registra una entidad
    /// </summary>
    /// <param name="entity"></param>
    void Insert(T entity);

    /// <summary>
    /// Actualiza una entidad
    /// </summary>
    /// <param name="entity"></param>
    void Update(T entity);

    /// <summary>
    /// Registra varias entidades
    /// </summary>
    /// <param name="entity"></param>
    void Insert(IEnumerable<T> entities);

    /// <summary>
    /// Actualiza varias entidades
    /// </summary>
    /// <param name="entity"></param>
    void Update(IEnumerable<T> entities);

    T FirstOrDefault();
    T FirstOrNew();
    double Max(Func<T, double> field, Expression<Func<T, bool>> where);
    double Max(Func<T, double> field);

    #endregion

    #region SQL Queries
    /// <summary>
    /// Ejecuta un query personalizado
    /// </summary>
    /// <param name="entity"></param>
    IQueryable<T> SelectQuery(string query, params object[] parameters);
    int ExecuteSqlCommand(string query, params object[] parameters);

    /// <summary>
    /// Ejecuta un query personalizado y espera un retorno a cambio
    /// </summary>
    /// <param name="entity"></param>
    IQueryable<I> ExecuteSqlCommand<I>(string query, params object[] parameters) 
where I : class;
    #endregion
}
}

Repository.cs

using Common.CustomFilters;
using Persistence.DatabaseContext;
using Persistence.DbContextScope;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;

namespace Persistence.Repository
{
public class Repository<T> : IRepository<T> where T : class, new()
{
    private readonly IAmbientDbContextLocator _ambientDbContextLocator;


    public Repository(IAmbientDbContextLocator context)
    {
        _ambientDbContextLocator = context;
    }

    private ApplicationDbContext DbContext
    {
        get
        {
            var dbContext = _ambientDbContextLocator.Get<ApplicationDbContext>();

            if (dbContext == null)
            {
                throw new InvalidOperationException("No ambient DbContext of type UserManagementDbContext found. This means that this repository method has been called outside of the scope of a DbContextScope. A repository must only be accessed within the scope of a DbContextScope, which takes care of creating the DbContext instances that the repositories need and making them available as ambient contexts. This is what ensures that, for any given DbContext-derived type, the same instance is used throughout the duration of a business transaction. To fix this issue, use IDbContextScopeFactory in your top-level business logic service method to create a DbContextScope that wraps the entire business transaction that your service method implements. Then access this repository within that scope. Refer to the comments in the IDbContextScope.cs file for more details.");
            }

            return dbContext;
        }
    }

    private IQueryable<T> PerformInclusions(IEnumerable<Expression<Func<T, object>>> includeProperties,
                                                   IQueryable<T> query)
    {
        return includeProperties.Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
    }

    #region IRepository<T> Members
    public IQueryable<T> AsQueryable()
    {
        return DbContext.Set<T>().AsQueryable();
    }

    public IEnumerable<T> GetAll(params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = AsQueryable();
        return PerformInclusions(includeProperties, query);
    }

    public IEnumerable<T> ThenInclude(params Expression<Func<T, object>>[] thenIncludeProperties)
    {
        IQueryable<T> query = AsQueryable();
        foreach (var item in thenIncludeProperties)
        {
            query = query.Include(item);
        }
        return query;
    }

    public IEnumerable<T> Find(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = AsQueryable();
        query = PerformInclusions(includeProperties, query);
        return query.Where(where);
    }

    public T Single(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = AsQueryable();
        query = PerformInclusions(includeProperties, query);
        return query.Single(where);
    }

    public T SingleOrDefault(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = AsQueryable();
        query = PerformInclusions(includeProperties, query);
        return query.SingleOrDefault(where);
    }
    public double Max(Func<T, double> field, Expression<Func<T, bool>> where)
    {

        IQueryable<T> query = AsQueryable();
        return query.Where(where).Max(field);
    }
    public double Max(Func<T, double> field)
    {
        IQueryable<T> query = AsQueryable();
        try
        {
            return query.Max(field);
        }
        catch (Exception)
        {

            return 0;
        }

    }

    public T First(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = AsQueryable();
        query = PerformInclusions(includeProperties, query);
        return query.First(where);
    }

    public T FirstOrDefault(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = AsQueryable();
        query = PerformInclusions(includeProperties, query);
        return query.FirstOrDefault(where);
    }

    public T FirstOrNew(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = AsQueryable();
        query = PerformInclusions(includeProperties, query);
        return query.FirstOrDefault(where) ?? new T();
    }

    public T FirstOrDefault()
    {
        IQueryable<T> query = AsQueryable();
        return query.FirstOrDefault();
    }


    public T FirstOrNew()
    {
        IQueryable<T> query = AsQueryable();
        return query.FirstOrDefault() ?? new T();
    }
    public void Delete(T entity)
    {
        if (entity is ISoftDeleted)
        {
            ((ISoftDeleted)entity).Deleted = true;

            DbContext.Set<T>().Attach(entity);
            DbContext.Entry(entity).State = EntityState.Modified;
        }
        else
        {
            DbContext.Set<T>().Remove(entity);
        }
    }

    public void DeleteRange(IEnumerable<T> entities)
    {
        foreach (var entity in entities)
        {
            if (entity is ISoftDeleted)
            {
                ((ISoftDeleted)entity).Deleted = true;

                DbContext.Set<T>().Attach(entity);
                DbContext.Entry(entity).State = EntityState.Modified;
            }
            else
            {
                DbContext.Entry(entity).State = EntityState.Deleted;
            }
        }
    }

    public void Insert(T entity)
    {
        DbContext.Set<T>().Add(entity);
    }

    public void Update(T entity)
    {
        DbContext.Set<T>().Attach(entity);
        DbContext.Entry(entity).State = EntityState.Modified;
    }

    public void Insert(IEnumerable<T> entities)
    {
        foreach (var e in entities)
        {
            DbContext.Entry(e).State = EntityState.Added;
        }
    }

    public void Update(IEnumerable<T> entities)
    {
        foreach (var e in entities)
        {
            DbContext.Entry(e).State = EntityState.Modified;
        }
    }
    #endregion

    #region SQL Queries
    public virtual IQueryable<T> SelectQuery(string query, params object[] parameters)
    {
        return DbContext.Set<T>().SqlQuery(query, parameters).AsQueryable();
    }

    public virtual int ExecuteSqlCommand(string query, params object[] parameters)
    {
        return DbContext.Database.ExecuteSqlCommand(query, parameters);
    }

    public IQueryable<I> ExecuteSqlCommand<I>(string query, params object[] parameters) where I : class
    {
        return DbContext.Database.SqlQuery<I>(query, parameters).AsQueryable();
    }
    #endregion
}
}

If you want to implement it you can see this base project which has this repository working

https://github.com/Anexsoft/asp.net-mvc-5-arquitectura-base/

You can search for Anexoft in Youtube there are some videos explaning the layers of this project

I hope it can help you.

José Polanco
  • 574
  • 4
  • 19