0
votes

I'm writing a simple logging mechanism for my app.

I have generic repository:

public class GenericRepository<TEntity>:IRepository<TEntity> where TEntity : class
{
    internal Equipment_TestEntities context;
    internal DbSet<TEntity> dbSet;
    internal Log entry;

    public GenericRepository(Equipment_TestEntities context)
    {
        this.context = context;
        this.dbSet = context.Set<TEntity>();
        this entry= new Log();
    }
    public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
        AddLog("insert "+typeof(TEntity)+" "+entity.ToString());
    }
    private void AddLog(string action)
    {
        entry.Action = action;
        entry.Date = DateTime.Now;
        string username = HttpContext.Current.User.Identity.Name;
        username = username.Substring(username.LastIndexOf("\\") + 1);
        entry.Who = 1;
        context.Logs.Add(entry);
    }
}

In entry.Action I want to keep:

  1. Action eg. Insert
  2. Which entityUsed eg. User or Role
  3. Something to identify entity

In 1) I can easily hardcone action 2) I can use TypeOf and get entity class name

But in 3rd I have a bit problem. In case of insert I can ask db for the newest record but what should I do in Edit/remove cases? Is there any ways to get properties value from those entities?

@Update:

sample part from unitOfWork:

public IRepository<Storage> storageRepository
    {
        get
        {
            if (this.StorageRepository == null)
            {
                this.StorageRepository = new GenericRepository<Storage>(context);
            }
            return StorageRepository;
        }
    }

IUnitOfWork: public interface IUnitOfWork : IDisposable { IRepository storageRepository { get; } }

1
Why not create an interface for your entities (where TEntity : IEntity) and then define an Id property in that interface?sroes
How should it look if not all entities/tables in Db have Id/PrimaryKey?szpic
There's something smelly with your code... I mean you are not using dependency injection correctly and btw private fields should (but not must) start with underscore - this is a naming convention and in constructor try to avoid writing this. You should rather write something like _context = context; and sorry I don't know the answer for your question.rosko
@szpic I think sroes is correct. If not all have primary key? Can't you make the field nullable for those cases?Jaycee
@rosko To your point about szpic's naming conventions - there is absolutely nothing wrong with this.variable vs _variable - as long as you're consistent (e.g. this.dbSet should be used instead of just dbSet in this case).dav_i

1 Answers

1
votes

I'd create an interface for the entities:

public interface IEntity
{
    int? Id { get; set; }
}

Then change the generic constraint:

public class GenericRepository<TEntity>:IRepository<TEntity> 
    where TEntity : class, IEntity
{
    ...
}

Now you can simply use entity.Id to identify your entities.:

public virtual void Remove(TEntity entity)
{
    if (!entity.Id.HasValue) {
        throw new Exception("Cannot remove " + entity + ", it has no ID");
    }
    ...
}