Skip to content

Commit

Permalink
Merge pull request #36 from threenine/feature/td-2-update-documentati…
Browse files Browse the repository at this point in the history
…on-enhancements

Feature/td 2 update documentation enhancements
  • Loading branch information
garywoodfine committed Aug 7, 2020
2 parents 1405453 + 9fd8d77 commit 212e81f
Show file tree
Hide file tree
Showing 17 changed files with 387 additions and 63 deletions.
26 changes: 5 additions & 21 deletions .github/PULL_REQUEST_TEMPLATE.md
@@ -1,26 +1,10 @@
## What type of PR is this? (check all applicable)
- [] Refactor
- [] Feature
- [] Bug Fix
- [] Optimization
- [] Documentation Update
- [ ] Refactor
- [ ] Feature
- [ ] Bug Fix
- [ ] Optimization
- [ ] Documentation Update

## Overview:
[A summary of what you did in no more than one paragraph]

## Work carried out:

[A list of work you have done, use markdown checklist format,
Don't bother to include list of files changed this will automatically be included]

example.
- [x] Updated packages in `package.json` to update references

## Practical usage example
[Sometimes the use of the code isn't immediately clear, if so, add a usable example here]

## Screenshot
[If the PR benefits from it then paste a screenshot of the update here.]

## Developer Notes:
[Sometimes, extra notes are needed to add clarity to a PR, add them here]
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -256,3 +256,5 @@ paket-files/
# JetBrains Rider
.idea/
*.sln.iml
tools/*
!tools/packages.config
26 changes: 23 additions & 3 deletions build.cake
@@ -1,19 +1,37 @@

#tool "nuget:?package=JetBrains.dotCover.CommandLineTools&version=2020.1.4"
var target = Argument("Target", "Default");
var configuration = Argument("Configuration", "Release");

Information($"Running target {target} in configuration {configuration}");

var distDirectory = Directory("./build");
var packageDirectory = Directory("./package");
var temporaryFolder = Directory("./temp");
TaskSetup(setupContext =>
{
if(TeamCity.IsRunningOnTeamCity)
{
TeamCity.WriteStartBuildBlock(setupContext.Task.Description ?? setupContext.Task.Name);
}
});

TaskTeardown(teardownContext =>
{
if(TeamCity.IsRunningOnTeamCity)
{
TeamCity.WriteEndProgress(teardownContext.Task.Description ?? teardownContext.Task.Name);
}
});

Task("Clean")
.Description("Cleaning the solution directory")
.Does(() =>
{
CleanDirectory(distDirectory);
});

Task("Restore")
.Description("Restoring the solution dependencies")
.Does(() =>
{
DotNetCoreRestore();
Expand Down Expand Up @@ -51,11 +69,13 @@ Task("Test")
});
}
});

Task("Default")
.IsDependentOn("Clean")
.IsDependentOn("Restore")
.IsDependentOn("Build")
.IsDependentOn("Test");

RunTarget(target);

RunTarget(target);

36 changes: 35 additions & 1 deletion docs/readonly-repository.md
@@ -1,6 +1,6 @@
# Read Only Repository

Threenine.Data supports readonly repository which enable retrieving data from from Entity Framework without the addiitional over head
Threenine.Data supports readonly repository which enable retrieving data from from Entity Framework without the additional over head
of the EF core query tracking.

Tracking behavior controls if Entity Framework Core will keep information about an entity instance in its change tracker. If an entity is tracked,
Expand All @@ -25,7 +25,41 @@ Use the SingleOrDefault method to get a single matching entity if one exists.

SingleOrDefault returns the default value for the entity, returning a single matching element, or the default value if no element is found.

```c#
var product = uow.GetRepository<TestProduct>().SingleOrDefault(x => x.Id == 1);
```
`SingleOrDefault` also enables the functionality to Order and Include before making the selection

```c#
var product = uow.GetRepository<TestProduct>().SingleOrDefault(orderBy: x => x.OrderBy(x => x.Name),
include: x => x.Include(x => x.Category));
```

#### GetList

Get list returns a paginated list of the items by default.

The really useful aspect of the `GetList` is that it comes with a built in pagination functionality, which can be customised for your specific purposes but is instantiated with intuitive defaults.

The default size settings for items returned by `GetList` method is supplied as 20. However this setting can be overridden in number of ways.

If you are unsure of the number records you want retrieved and would like the repository to return as many as possible you can simply pass the `size: int.MaxValue` setting

``` c#
var repo = uow.GetRepository<SomeEntity>().GetList(size: int.MaxValue).Items;
```

You can also provide a predicate containing the where clause you want to extract records on and supply a size counter for the number of records you want to appear on each page

```c#
var items = uow.GetRepository<SomeEntity>().GetList(x => x.CategoryId == 1 ).Items

// or
var result = uow.GetRepository<SomeEntity>().GetList(x => x.CategoryId == 1 );

var theItems = result.Items

```



22 changes: 19 additions & 3 deletions src/DeleteRepository.cs
@@ -1,17 +1,33 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

namespace Threenine.Data
{
public class DeleteRepository<T> : IDeleteRepository<T> where T : class
{
private readonly DbContext _dbContext;
private readonly DbSet<T> _dbSet;

public DeleteRepository(DbContext context)
{
_dbContext = context ?? throw new ArgumentException(nameof(context));
_dbSet = _dbContext.Set<T>();
var dbContext = context ?? throw new ArgumentException(nameof(context));
_dbSet = dbContext.Set<T>();
}

public void Delete(T entity)
{
_dbSet.Remove(entity);
}

public void Delete(params T[] entities)
{
_dbSet.RemoveRange(entities);
}


public void Delete(IEnumerable<T> entities)
{
_dbSet.RemoveRange(entities);
}
}
}
7 changes: 7 additions & 0 deletions src/IDeleteRepository.cs
@@ -1,6 +1,13 @@
using System.Collections.Generic;

namespace Threenine.Data
{
public interface IDeleteRepository<T> where T : class
{
void Delete(T entity);

void Delete(params T[] entities);

void Delete(IEnumerable<T> entities);
}
}
2 changes: 1 addition & 1 deletion src/IRepository.cs
Expand Up @@ -25,7 +25,7 @@ namespace Threenine.Data
{
public interface IRepository<T> : IReadRepository<T>, IDisposable where T : class
{
T GetSingleOrDefault(Expression<Func<T, bool>> predicate = null,
T SingleOrDefault(Expression<Func<T, bool>> predicate = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
Func<IQueryable<T>, IIncludableQueryable<T, object>> include = null,
bool enableTracking = true,
Expand Down
1 change: 1 addition & 0 deletions src/IUnitOfWork.cs
Expand Up @@ -27,6 +27,7 @@ public interface IUnitOfWork : IDisposable
IRepositoryAsync<TEntity> GetRepositoryAsync<TEntity>() where TEntity : class;
IRepositoryReadOnly<TEntity> GetReadOnlyRepository<TEntity>() where TEntity : class;
IRepositoryReadOnlyAsync<TEntity> GetReadOnlyRepositoryAsync<TEntity>() where TEntity : class;
IDeleteRepository<TEntity> DeleteRepository<TEntity>() where TEntity : class;


int Commit(bool autoHistory = false);
Expand Down
2 changes: 1 addition & 1 deletion src/Repository.cs
Expand Up @@ -32,7 +32,7 @@ public Repository(DbContext context) : base(context)

#region Get Functions

public T GetSingleOrDefault(Expression<Func<T, bool>> predicate = null,
public T SingleOrDefault(Expression<Func<T, bool>> predicate = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
Func<IQueryable<T>, IIncludableQueryable<T, object>> include = null, bool enableTracking = true,
bool ignoreQueryFilters = false)
Expand Down
6 changes: 6 additions & 0 deletions src/UnitOfWork.cs
Expand Up @@ -58,6 +58,12 @@ public UnitOfWork(TContext context)
new RepositoryReadOnlyAsync<TEntity>(Context));
}

public IDeleteRepository<TEntity> DeleteRepository<TEntity>() where TEntity : class
{
return (IDeleteRepository<TEntity>) GetOrAddRepository(typeof(TEntity),
new DeleteRepository<TEntity>(Context));
}

public TContext Context { get; }

public int Commit(bool autoHistory = false)
Expand Down
40 changes: 40 additions & 0 deletions tests/Threenine.Data.Tests/DeleteRepositoryTests.cs
@@ -0,0 +1,40 @@
using System;
using TestDatabase;
using Threenine.Data.Tests.TestFixtures;
using Xunit;

namespace Threenine.Data.Tests
{
[Collection(GlobalTestStrings.ProductCollectionName)]
public class DeleteRepositoryTests : IDisposable
{
private readonly SqlLiteWith20ProductsTestFixture _fixture;
public DeleteRepositoryTests(SqlLiteWith20ProductsTestFixture fixture)
{
_fixture = fixture;
}

[Fact]
public void ShouldDeleteProduct()
{
using var uow = new UnitOfWork<TestDbContext>(_fixture.Context);

var getRepo = uow.GetRepository<TestProduct>();
var delRepo = uow.DeleteRepository<TestProduct>();

uow.Commit();

var prod = getRepo.SingleOrDefault(x => x.Id == 1);
delRepo.Delete(prod);
uow.Commit();

prod = getRepo.SingleOrDefault(x => x.Id == 1);
Assert.Null(prod);
}

public void Dispose()
{
_fixture?.Dispose();
}
}
}

0 comments on commit 212e81f

Please sign in to comment.