Alice52 / c-tutorial

The repository is about c, including c, csharp, cpp.
MIT License
0 stars 0 forks source link

[efcore] efcore knowledge list #7

Open Alice52 opened 4 years ago

Alice52 commented 4 years ago

folder strcut

│  xxx.DataAccess.csproj
│
├─Db
│      IReadDbFacade.cs
│      IRepository.cs
│      ReadDbFacade.cs
│      Repository.cs
│      xxDbContext.cs
│      xxxContextFactory.cs
│      xxxContextScope.cs
│      xxxContextScopeFactory.cs
│      xxxPartialDbContext.cs
│
├─DBScript
│  └─InitData
│          xx.sql
│
├─Migrations
│      20200312025749_xxx.cs
│      20200312025749_xxx.Designer.cs
│      20200312025749_xxx.sql
│      xxDbContextModelSnapshot.cs
│
├─Models
│  │  xxxModel.cs
│  │
│  └─Configurations
│          xxxModelConfiguration.cs
│
└─Repositories
        IxxxTRepository.cs
        xxxRepository.cs

code first


usage mode

  1. repository

  2. readDbFacade

  3. repostory sample

// repository definition
public class Repository<TAggregateRoot> : IRepository<TAggregateRoot> where TAggregateRoot : class
{
    protected readonly IAmbientDbContextLocator _dbContextLocator;
    public Repository(IAmbientDbContextLocator dbContextLocator)
    {
        if (dbContextLocator == null)
            throw new ArgumentNullException(nameof(dbContextLocator) + " is null");

        _dbContextLocator = dbContextLocator;
    }
    protected DbSet<TAggregateRoot> Set => TableOperationDbContext.Set<TAggregateRoot>();
    protected TableOperationDbContext TableOperationDbContext
    {
        get
        {
            var TableOperationDbContext = _dbContextLocator.Get<TableOperationDbContext>();
            if (TableOperationDbContext == null)
                throw new InvalidOperationException();
            return TableOperationDbContext;
        }
    }
    public virtual void Save()
    {
        TableOperationDbContext.SaveChanges();
    }
    public bool DoesExist(Expression<Func<TAggregateRoot, bool>> matchingCriteria)
    {
        return Set.Any(matchingCriteria);
    }
    public virtual TAggregateRoot GetById(long id)
    {
        return Set.Find(id);
    }
    public void BulkInsert(IEnumerable<TAggregateRoot> aggregateRoots)
    {
        Set.AddRange(aggregateRoots);
    }
    public void Insert(TAggregateRoot entity)
    {
        Set.Add(entity);
    }
    public void InsertAndSave(TAggregateRoot aggregateRoot)
    {
        Set.Add(aggregateRoot);
        TableOperationDbContext.SaveChanges();
    }
    public virtual void Delete(long id)
    {
        var entityToDelete = Set.Find(id);
        Delete(entityToDelete);
    }
    public void Delete(TAggregateRoot aggregateRoot)
    {
        Set.Remove(aggregateRoot);
    }
    public void BulkDelete(IEnumerable<TAggregateRoot> aggregateRoots)
    {
        Set.RemoveRange(aggregateRoots);
    }
    public IList<TAggregateRoot> GetAll()
    {
        return Set.ToList();
    }
    public void Update(TAggregateRoot aggregateRoot)
    {
        Set.Update(aggregateRoot);
    }
}

# usage repository
public class xxRepository : Repository<xx>, IxxRepository
{
    public xxRepository(IAmbientDbContextLocator dbContextLocator) : base(dbContextLocator)
    {
    }
    public RatingMapping GetByxx(string xx)
    {
        return Set.Where(x => x.xx.Equals(xx)).FirstOrDefault();
    }
}

using (var dbScope = _dbContextScopeFactory.CreateWithTransaction(IsolationLevel.ReadCommitted))
{
    // logic
    dbScope.SaveChanges();
}
  1. readfacade sample
// read facade definition
public class ReadDbFacade : IReadDbFacade, IDisposable
{
    private readonly xxDbContext _readTableDbContext;
    public ReadDbFacade(xxnDbContext readDbContext)
    {
        _readTableDbContext = readDbContext;
    }
    public IQueryable<xxx> xxxs => _readTableDbContext.xxx;
    public void Dispose()
    {
        _readTableDbContext.Dispose();
    }
}

// usage of read faxade
var xx = _readDbFacade.xxxs
    .Where(p => p.xx == xxx)
    .FirstOrDefault();

primary key

- if the key is 36 bit nvarch, efcore will auto fillin NEWID() to it and we should do nothing
- can config default value of columns in xxConfigrations, which is modelbuild file 

perfomance

  1. update:

    • using repository mode, can not use update, and use dbScope.SaveChanges()
    • if use update(), it will update all column
    • else it will update changed column

cache

  1. use Transient services.AddTransient<ITableService, TableService>(); to inspect in startup

  2. use 1 and async

    • await dbScope.SaveChangesAsync();
    • dbScope.SaveChangesAsync().Result;
    • dbScope.SaveChangesAsync().GetAwaiter().GetResult();