none
repositorio generico crud RRS feed

  • Pregunta

  • hola un saludo a la comunidad, la pregunta es como hacer un crud en repositorio genérico.

    public abstract class BaseModel<T>
        {
            [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
            public virtual T Id { get; set; }
    
            [Required, StringLength(maximumLength: 250)]
            public virtual string Name { get; set; }
    
            //[StringLength(maximumLength: 1000)]
            //public virtual string Description { get; set; }
        }
    public class Menus:BaseModel<int>,IObjectWithState
        {
            public override int Id { get; set; }
            public override string Name { get; set; }
            public string MenuId { get; set; }
            public string State { get; set; }
            public string Icon { get; set; }
            public string Href { get; set; }        
            public DateTime Creado { get; set; }
            public DateTime Modificado { get; set; }
    
            public virtual ICollection<Usuarios> Usuarios { get; set; }
    
            [NotMapped]
            State IObjectWithState.State { get; set; }
        }


     public class Usuarios:BaseModel<int>,IObjectWithState
        {
            public override int Id { get; set; }
            public override string Name { get; set; }
            public string UserName { get; set; }
            public DateTime Creado { get; set; }
            public DateTime Modificado { get; set; }
            public bool Activo { get; set; }
    
            public virtual ICollection<Menus> Menus { get; set; }
    
            [NotMapped]
            State IObjectWithState.State { get; set; }
        }


     public interface IObjectWithState
        {
            State State { get; set; }
        }
    
        public enum State
        {
            Added,
            Unchanged,
            Modified,
            Deleted
        }


    public abstract class BaseRepository : IRepository
        {
            private readonly IDbContext context;
    
            public BaseRepository(IDbContext context)
            {
                this.context = context;
            }
    
            public IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class
            {
                return GetEntities<TEntity>().AsQueryable();
            }
    
            public void Insert<TEntity>(TEntity entity) where TEntity : class
            {
                GetEntities<TEntity>().Add(entity);
            }
            
            public void Delete<TEntity>(TEntity entity) where TEntity : class
            {
                GetEntities<TEntity>().Remove(entity);
            }
    
            private IDbSet<TEntity> GetEntities<TEntity>() where TEntity : class
            {
                return this.context.Set<TEntity>();
            }
    
            public void SaveChanges()
            {
                this.context.SaveChanges();
            }
    
            public void Dispose()
            {
                if (this.context != null)
                {
                    this.context.Dispose();
                }
            }
    
            public void Update<TEntity>(TEntity entity) where TEntity:class
            {
                foreach (var item in entity)
                {
                    if (item.GetType().GetProperty("") == null)
                    {
                        var res = item;
                    }
                }
               
            }
    
            public TEntity GetById<TEntity>(int id) where TEntity : BaseModel<int>
            {
                return (from item in GetAll<TEntity>()
                        where item.Id == id
                        select item).SingleOrDefault();
            }
        }

    la cuestión es que en el método update necesito recorrer sus propiedades y ponerles un estado según sea el caso (Added, Unchanged, Modified, Deleted) y despues guardar el objeto...


    LOWELLPELIKNO

    miércoles, 18 de mayo de 2016 2:22

Todas las respuestas

  • hola

    analiza

    Implementing a generic data access layer using Entity Framework

    el titulo "Persisting disconnected graphs" del articulo

    alli veras que usa

    foreach (T item in items)
            {
                dbSet.Add(item);
                foreach (DbEntityEntry<IEntity> entry in context.ChangeTracker.Entries<IEntity>())
                {
                    IEntity entity = entry.Entity;
                    entry.State = GetEntityState(entity.EntityState);
                }
            }

    para asignar el estado de las entidades que fueron afectadas

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    miércoles, 18 de mayo de 2016 10:19
  • Viera que no entiendo bien la pregunta.  Usted dice que debe "ponerles un estado según sea el caso", pero ¿no es eso algo que debe de suceder naturalmente?  En mis repositorios, la clase base Entity implementa INotifyPropertyChanged y tiene la propiedad IsDirty que automáticamente adquiere el valor true cuando alguna propiedad cambia su valor.  También tengo una propiedad IsDeleted y sé si es Added si el ID es cero (porque normalmente mis PK's son numéricos).  Pero me gusta la idea del enum. :-)

    En fin, por eso es que no entiendo su pregunta.  Para mí, el cambio del estado se da mucho antes de entrar al Update.


    Jose R. MCP
    Code Samples

    miércoles, 18 de mayo de 2016 14:31
  • gracias por sus respuestas.

    bien se presenta este caso:

    tengo la entidad usuarios la cual a su ves tiene una coleccion de menus.

    la duda es que al construir el objeto usuarios para guardarlos en la bd debe checar si algunos items de la lista menus van en estado add o delete o update,  tambien son envase al id de cada item, si va un Id entonces el registro se actualiza o se elimina de lo contrario se agrega. por eso la pregunta.

    ese seria el caso.


    LOWELLPELIKNO

    miércoles, 18 de mayo de 2016 14:45
  • >>la duda es que al construir el objeto usuarios para guardarlos en la bd debe checar si algunos items de la lista menus van en estado add o delete o update

    pero para eso haces que las entidades implementen IObjectWithState

    en el articulo que sugiero aplica lo mismo pero usando IEntity

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    miércoles, 18 de mayo de 2016 14:57
  • una duda leandro..

    en el ejemplo que proporcionas esta linea

    using (var context = new Entities())

    pero que viene siendo Entities();


    LOWELLPELIKNO

    miércoles, 18 de mayo de 2016 15:28
  • hola

    seria el contexto de EF

    si revisas el titulo "Disconnected entities" veras que define

        public partial class Entities : DbContext


    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    miércoles, 18 de mayo de 2016 17:26
  • hola de nuevo. ya implementando el ejemplo del link que proporcionas leandro. tengo esto en la base de datos

    este es el codigo

    static void Main(string[] args)
            {
                //Get_All_Category();
                //Get_ListUsuario_Menu();
                //RemoveUsuario();
                ///insertUsuario();
                AddRelations();
                Console.ReadLine();
            }       
            public static void AddRelations()
            {
                Console.WriteLine("entro bien");
    
                UsuariosRepository businnes = new UsuariosRepository();
                IList<Menus> menusList = businnes.GetAllMenus();
                Usuarios user = businnes.GetUsuarioById(1);
                foreach (Menus department in menusList)
                {
                    if (department.Id == 2)
                        user.Menus = new List<Menus>
                    {
                        new Menus
                        {
                            Name = department.Name,
                            MenuId = department.MenuId,
                            State = department.State,
                            Icon = department.Icon,
                            Href = department.Href,
                            Creado = DateTime.Now,
                            Modificado = DateTime.Now,
                            MyState = MyState.Added
                        }
                    };
                }
                user.MyState = MyState.Modified;
                businnes.InsertUpdate(user);
                Console.WriteLine("termino bien");
            }

    el repositorio

    public class UsuariosRepository: BaseRepository<Usuarios>, IBusinessLayer { private readonly IUsuariosRepository _userRepository; private readonly IMenusRepository _menuRepository; public UsuariosRepository() { _userRepository = new UsuariossRepository(); _menuRepository = new MenusRepository(); } public UsuariosRepository(IMenusRepository menuRepository, IUsuariosRepository usuarioRepository) { _menuRepository = menuRepository; _userRepository = usuarioRepository; } public IList<Menus> GetAllMenus() { return _menuRepository.GetAll(); } public Usuarios GetUsuarioById(int id) { return _userRepository.GetSingle(e => e.Id == id); } }

    public virtual void InsertUpdate(params T[] items)
            {
                using (var context = new NorthWindContext())
                {
                    DbSet<T> dbSet = context.Set<T>();
                    foreach (T item in items)
                    {
                        dbSet.Add(item);
                        foreach (DbEntityEntry<IObjectWithState> entry in context.ChangeTracker.Entries<IObjectWithState>())
                        {
                            IObjectWithState entity = entry.Entity;
                            entry.State = CheckStates.ConvertState(entity.MyState);
                        }
                    }
                    context.SaveChanges();
                }
            }

    si checan las tablas en la bd, ya se encuentran registrados datos en las tablas principales "menus" y "usuarios", ahora como puedo agregarle una relacion al usuario, sabiendo que N-Menus le pueden pertenecer??

    lo que esta pasando esque me agrega un nuevo registro en la tabla "menus".


    LOWELLPELIKNO



    miércoles, 18 de mayo de 2016 21:00