furkandeveloper / easyrepository.efcore Goto Github PK
View Code? Open in Web Editor NEWThis repo provides implementation generic repository pattern and specification pattern on Entity Framework Core
License: MIT License
This repo provides implementation generic repository pattern and specification pattern on Entity Framework Core
License: MIT License
I would like to add an overload that takes Enum.AsNoTracking
to all of the methods. For example, currently there might be a method such as this:
I would like to add an overload that takes an enum
instead of bool
In this enhancement I suggest we:
bool
parameterbool
parameterWhat do you suggest?
Explicit parameters help the developer. using a bool of true
or false
can mean anything. The developer must look at the xml
notes in order to see "Ah yes... this is for change tracking"
Here are some articles about it:
Additional context
I will need your advice and suggestions on naming the classes and properties.
I suggest these, please let me know your input and feel free to rename or re-design
Enum
public enum EfTrackingOptions
{
/// <summary>
/// Disables EfCore change tracking
/// </summary>
AsNoTracking,
/// <summary>
/// Enables EfCore Change Tracking
/// </summary>
WithTracking
}
Extension Method
internal static class EfTrackingOptionExtensions
{
public static bool HasNoTracking(this EfTrackingOptions options)
{
return options == EfTrackingOptions.AsNoTracking;
}
}
bool
, or option 2 of add the overload and remove the bool
parameterenum class name and property names
extension method class name and method name
I propose we change IEnumerable<TEntity>
to ICollection<TEntity>
on the methods which have the entities.ToList()
My thoughts are:
.ToList()
so we lose all advantages IEnumerable could offernetstandard2.1
not netstandard2.0
unless if they perform these steps https://btburnett.com/csharp/2019/12/01/iasyncenumerable-is-your-friend.htmlSolutions:
1.) Change to IAsynEnumerable
or
2.) Use ICollection
instead if IEnumerable
Which do you think would be better?
Should I make these changes? What are your thoughts on option 1 or 2?
Basically this Feature request is to enable: Nullable Reference Types
If approved, I can implement this change
In favor of being explicit, nullable reference types will highlight and throw errors when null is returned when it is not expected. Such as:
private Expression<Func<TEntity, bool>> GenerateExpression<TEntity>(object id)
{
// Type might be null
var type = this._context.Model.FindEntityType(typeof(TEntity));
// Type might be null.. If this is not 'caught' then it will throw NullReference Error.
// Instead... We can 'catch' the Null Reference Error and then throw an error such as:
// EasyRepositoryTypeNotFoundException : Exception
// Message: The Type TypeOf(TEntity).Name was not found, please ensure it exists within the DBContext model as a registered
// DbSet<TEntity>.
//---- This is a change in favor of being 'explicit'.
var pk = type.FindPrimaryKey()
.Properties.Select(s => s.Name)
.FirstOrDefault();
// Type might also be null here
var pkType = type.FindPrimaryKey()
.Properties.Select(p => p.ClrType)
.FirstOrDefault();
// PkType might be null here also
var value = Convert.ChangeType(id, pkType, CultureInfo.InvariantCulture);
var pe = Expression.Parameter(typeof(TEntity), "entity");
var me = Expression.Property(pe, pk);
var constant = Expression.Constant(value, pkType);
var body = Expression.Equal(me, constant);
var expression = Expression.Lambda<Func<TEntity, bool>>(body, pe);
return expression;
}
Further Reading of advantages:
EasyRepositoryTypeNullException
and other exception types for EasyRepository
such as EasyRepositoryPrimaryKeyNotFoundException
, and othersEasyRepository
does not expect null to be returned. Then we would throw an exception instead of .NET xxx
throwing a NullReferenceTypeException
Personally, I like to be explicit in code, it helps prevent and diagnose errors. I think Nullable Reference types will lower the likely-hood of future bugs, and also help the developer user (consumer of EasyRepository
library) diagnose bugs.
I can add this feature if approved
What is Unit Of Work?
Unit of Work is the concept related to the effective implementation of the Repository Pattern. To understand this concept in better it is important to understand the concept of the Repository Pattern. We will not get into the details of the Repository Pattern in this discussion. But a small idea of this concept is necessary to proceed further.
EasyRepository.EFCore must be support DDD based specification model.
One Domain-Driven-Design solution to the problem of where to place querying, sorting, and paging logic is to use a Specification. The Specification design pattern describes a query in an object. So to encapsulate a paged query that searches for some products, one might create a PagedProduct specification which would take in any necessary parameters (pageSize, pageNumber, filter). Then one of your repository methods (usually a List() overload) would accept an ISpecification and would be able to produce the expected result given the specification. There are several benefits to this approach. The specification has a name (as opposed to just a bunch of LINQ expressions) that you can reason about and discuss. It can be unit tested in isolation to ensure correctness. And it can easily be reused if you need the same behavior (say on an MVC View action and a Web API action, as well as in various services). Further, a specification can also be used to describe the shape of the data to be returned, so that queries can return just the data they required. This eliminates the need for lazy loading in web applications (bad idea) and helps keep repository implementations from becoming cluttered with these details.
Additional context
There is no need to make a native implementation. Ardalis.Specification library should be supported by default.
Entity framework core 7 version provides bulk delete and bulk update operations.
This feature runs like a mongo query. So, the provider generates a single query and runs it on the database.
Additional context
Can visit Microsoft ef-core documentation for this.
https://devblogs.microsoft.com/dotnet/announcing-ef7/#bulk-updates-and-deletes
Implement Update Operations for Abstraction Layer
The end user (developer) should be able to operate both on their own assets and on the base entity assets provided on EasyRepository.
This should be considered when applying the Abstraction of Repository pattern.
When the end user wants to use the library, he should simply use it without making any changes in his own application.
If the end user wants to use fields such as PrimaryKey, CreateDate, UpdateDate, DeleteDate and IsDeleted automatically, they should be able to use these features with a base entity by EasyProfiler.
The Abstraction of Repository must be supported in two operations on the pattern.
For Example for EasyBaseEntity
public abstract class EasyBaseEntity<TPrimaryKey> : IEasyEntity<TPrimaryKey>, IEasyCreateDateEntity, IEasyUpdateDateEntity, IEasySoftDeleteEntity
{
public virtual DateTime CreationDate { get; set; }
public virtual TPrimaryKey Id { get; set; }
public virtual DateTime? ModificationDate { get; set; }
public virtual DateTime? DeletionDate { get; set; }
public virtual bool IsDeleted { get; set; }
}
/// <summary>
/// Abstraction of Entity
/// </summary>
internal interface IEasyEntity<TPrimaryKey>
{
TPrimaryKey Id { get; set; }
}
public interface IEasyCreateDateEntity
{
public DateTime CreationDate { get; set; }
}
public interface IEasyUpdateDateEntity
{
public DateTime? ModificationDate { get; set; }
}
public interface IEasySoftDeleteEntity
{
public DateTime? DeletionDate { get; set; }
public bool IsDeleted { get; set; }
}
Implement delete operations for generic repository on interface layer
Implement add and addrange operations on generic repository of interface layer
EasyRepository must be implement the following items;
I am not sure if there is a reason why this is not implemented, perhaps you have done some tests and its not as simple as it looks.
Is there any reason why Transactions
and Rollback
is not implemented?
Is this something that you'd like me to add?
Is there any particular feature or way you would like this to be implemented?
I would like to remove all namespace scoped brackets, in favor of file-scoped namespaces.
No code changes will be required, as currently each file only uses one namespace - so this is a perfect scenerio to change to file scoped namespaces
Additional context
Additional Reading topics
I was working with Pagination, and I found the way it was currently implemented to be restricting. I found (1) bug, and (1) major improvement that could be made.
For my own projects, this is a reason why I would not use this library (no offense). Many people need pagination to return:
Standard Pagination Response Object:
https://stackoverflow.com/questions/12168624/pagination-response-payload-from-a-restful-api
{
"_metadata":
{
"page": 5,
"per_page": 20,
"page_count": 20,
"total_count": 521,
"Links": [
{"self": "/products?page=5&per_page=20"},
{"first": "/products?page=0&per_page=20"},
{"previous": "/products?page=4&per_page=20"},
{"next": "/products?page=6&per_page=20"},
{"last": "/products?page=26&per_page=20"},
]
},
"records": [
{
"id": 1,
"name": "Widget #1",
"uri": "/products/1"
},
{
"id": 2,
"name": "Widget #2",
"uri": "/products/2"
},
{
"id": 3,
"name": "Widget #3",
"uri": "/products/3"
}
]
}
Something like this^^
The key is to get this back as a JSON response object:
{
"page": 5,
"per_page": 20,
"page_count": 20,
"total_count": 521,
"Links": [
{"self": "/products?page=5&per_page=20"},
{"first": "/products?page=0&per_page=20"},
{"previous": "/products?page=4&per_page=20"},
{"next": "/products?page=6&per_page=20"},
{"last": "/products?page=26&per_page=20"},
]
}
or at the minimum return this as a JSON response object:
{
"page": 5,
"per_page": 20,
"page_count": 20,
"total_count": 521,
}
public List<TEntity> GetMultiple<TEntity, TFilter>(EfTrackingOptions asNoTracking, TFilter filter)
where TEntity : class
where TFilter : FilterBase
{
return this.FindQueryable<TEntity>(asNoTracking)
.ApplyFilter(filter)
.ToList();
}
What is currently implemented (This is the bug):
I propose (2) things:
EasyRepository.EfCore.AutoFilterer
-- This will allow us to implement new filter implementation using Gridify, Sieve and others, instead of currently we are 'married' to AutoFiltererThis is the improvement I mentioned in the beginning of my post.
TFilter
object instead of the TEntity
Object. This will be a 'breaking change' as it involves changing what currently implemented methods return.Paged
or Filtered
to the method. I prefer the suffix of Paged
as mostly all Filtered
use-cases for UI's will also be Paged
.To be honest, I need these methods in my own implementation, so I will get started on this. If you reject this proposal I 100% understand, and I will keep the code to myself.
If you think this is helpful and useful, I will add my code and create a pull-request so that our branches can be 'in-sync'.
What are your thoughts? Please make any changes or suggestions as you see fit.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.