none
how to in repository pattern get Insert Id RRS feed

  • Question

  • hi

    i use from repository pattern below like , this is correct and just i have a problem for get insert row id (identity id)

    in model class:

    public interface IEntity<T> { T Id { get; set; } } public abstract class BaseEntity { } public abstract class Entity<T> : BaseEntity, IEntity<T> { public virtual T Id { get; set; } }

     public class Country : Entity<int>
        {

            [Required]
            [MaxLength(100)]
            [Display(Name = "Country Name")]
            public string Name { get; set; }

    in Repository class

    public interface IGenericRepository<T> where T : BaseEntity
        {
            T Add(T entity);    
            void Save();
        }
    public abstract class GenericRepository<T> : IGenericRepository<T>
          where T : BaseEntity
        {
            protected DbContext _entities;
            protected readonly IDbSet<T> _dbset;
    
            public GenericRepository(DbContext context)
            {
                _entities = context;
                _dbset = context.Set<T>();
            }
    }
     public virtual T Add(T entity)
            {
              
                return _dbset.Add(entity);
            }
    public virtual void Save()
            {
                _entities.SaveChanges();
            }
     public interface IUnitOfWork : IDisposable
        {  int Commit();
        }
     public sealed class UnitOfWork : IUnitOfWork
        {  
    private DbContext _dbContext;
    public UnitOfWork(DbContext context)
            {
                _dbContext = context;
            }
     public int Commit()
            {
                // Save changes with the default options
                return _dbContext.SaveChanges();;
            }
    }
    public interface ICountryRepository : IGenericRepository<Country>
        {
            Country GetById(int id);
        }
    public class CountryRepository : GenericRepository<Country>, ICountryRepository
        {
            public CountryRepository(DbContext context)
                : base(context)
            {
            }
            public Country GetById(int id)
            {
                return FindBy(x => x.Id == id).FirstOrDefault();
            }
        }

    and in Service class:

     public interface IService
        {
        }
    public interface IEntityService<T> : IService
       where T : BaseEntity
        {
            void Create(T entity);
        }
     public abstract class EntityService<T> : IEntityService<T> where T : BaseEntity
        {
            IUnitOfWork _unitOfWork;
            IGenericRepository<T> _repository;
    
            public EntityService(IUnitOfWork unitOfWork, IGenericRepository<T> repository)
            {
                _unitOfWork = unitOfWork;
                _repository = repository;
            }
    public virtual void Create(T entity)
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }
                _repository.Add(entity);
               var id= _unitOfWork.Commit();
            }
    }
     public interface ICountryService : IEntityService<Country>
        {
            Country GetById(int Id);
        }
        public class CountryService : EntityService<Country>, ICountryService
        {
            IUnitOfWork _unitOfWork;
            ICountryRepository _countryRepository;
    
            public CountryService(IUnitOfWork unitOfWork, ICountryRepository countryRepository)
                : base(unitOfWork, countryRepository)
            {
                _unitOfWork = unitOfWork;
                _countryRepository = countryRepository;
            }
    
    
            public Country GetById(int Id)
            {
                return _countryRepository.GetById(Id);
            }
        }

    and in test class

     _CountryService.Create(country);

    now how to get Identity id after insert

    please help me thanks

    Saturday, September 20, 2014 5:28 AM

Answers

All replies

  • The DbContext (which is already a repository BTW so I'm not sure why you need to wrap in an your own repository), anyway the DbContext will fetch the indenty value after insert and populate it on the object.

    After SaveChanges() the id will be populated on the entity.

    David


    David http://blogs.msdn.com/b/dbrowne/

    Saturday, September 20, 2014 4:22 PM
  • thanks for your answer

    ok , how to get after  SaveChanges()

    please help me

    thanks

    Sunday, September 21, 2014 6:24 AM
  • I don't understand that question.  The ID will be populated on the object.  So just look at the property on the object after SaveChanges().

    David


    David http://blogs.msdn.com/b/dbrowne/

    Sunday, September 21, 2014 1:59 PM
  • thanks for your answer

    Usually normal us get identity id below like:

    _db.AddObject(country)

    _db.SaveChanges();

    return country.Id

    but in my pattern, the SaveChanges() called in UnitOfWork class

    public UnitOfWork(DbContext context)
            {
                _dbContext = context;
            }
     public int Commit()
            {
                // Save changes with the default options
                return _dbContext.SaveChanges();;
            }
    }

    and i don't accsess to entity for get (country.Id)

    if it's not clear ,please tell me for more information

    please help me

    thanks

    Sunday, September 21, 2014 3:23 PM
  • Sounds like your UOW wrapper is not useful. Why are you wrapping all the EF classes in you own custom wrappers? It just makes your code hard to read, and it's getting in your way.

    David


    David http://blogs.msdn.com/b/dbrowne/


    Sunday, September 21, 2014 7:14 PM
  • thanks for your tracking

    please you show a better solution

    thanks

    Monday, September 22, 2014 7:08 AM
  • >please you show a better solution

    Throw away all the Repository and Unit-of-work pattern cruft and just use the DbContext directly in your Service.  The Service is the last useful abstraction in your model.

    .NET has a perfectly serviceable way to group logical operations in a unit-of-work, the TransactionScope, which allows you to orchestrate multiple DbContext operations into a logical transaction and control the fate of the transaction in the business layer. 

    A functional UOW wrapper minimally would distinguishing between saving changes to the data store, and committing those changes.  A Unit-of-Work should be defined by a Transaction, not by a batch of in-memory changes.  There are multiple changes in a batch, and multiple batches in a transaction.   Very frequently in a unit of work you will have to write data to the back-end in the middle of your unit-of-work.

    David


    David http://blogs.msdn.com/b/dbrowne/

    Monday, September 22, 2014 1:43 PM
  • thanks for your answer

    but i want use Repsitory pattern no another pattern

    if you can change same of layer into Repository pattern for handle Savechange inside my entity

    please help me

    thanks

    Monday, September 22, 2014 3:35 PM
  • >but i want use Repsitory pattern no another pattern

    You are.  Your DbContext sublass is an implementation of the repository pattern.  You can add additional convenience methods or add an interface  to it in an additional partial class file.

    David


    David http://blogs.msdn.com/b/dbrowne/

    • Marked as answer by vahidbakhtiary Tuesday, September 23, 2014 7:40 AM
    Monday, September 22, 2014 3:46 PM
  • thanks for your help

    i resolve it

    • Marked as answer by vahidbakhtiary Tuesday, September 23, 2014 7:40 AM
    Tuesday, September 23, 2014 7:40 AM
  • How you resolved i am facing same issue.
    Monday, April 23, 2018 12:37 PM
  • How you resolved i am facing same issue.

    Resolve what?
    Monday, April 23, 2018 7:30 PM