Repository navigation
Releases: ProphetManX/ProphetsWay.EFTools
Release list
3.0.0
v3.0.0
Not yet published — nuget.org still serves 2.2.0 as the latest version of this package. Everything below is a
change against that published 2.2.0 package.
This is a rewrite of the library on top of Entity Framework Core alone, and it breaks nearly every consumer.
Read the whole entry before upgrading. There are no compatibility wrappers and none are planned; if the
migration is not worth your afternoon, 2.2.x remains installable and is unchanged — but read the next section
before you decide, because unchanged includes four defects this release fixes.
If you are on 2.2.0: four defects you are exposed to, and three of them are silent
The published 2.2.0 package carries four defects. Three of the four fail silently — no exception, no
failed build, no log line, just wrong data — so never having noticed one is not evidence you are unaffected.
Each has its own Fixed: section further down; this is the short list, so that a reader who is not
upgrading does not have to read the rest of the entry to find them.
- A leaked context and a leaked connection per Data Access Layer instance.
BaseEFDataAccess
constructed its ownDbContextand never disposed it, and there was noDisposefor you to call
either. This is the one that is not silent forever: it surfaces as connection-pool exhaustion under load,
and it is attributable once you go looking. - Commit and rollback that silently do nothing. The keyless Data Access Object base began a transaction
only when none was already open, then reached the transaction it never stored through?.when
committing and rolling back. Both calls returned normally having done nothing at all. Updatethat un-deletes a soft-deleted row. Whole-object replacement wiped the stored
DeletedDate, so updating a soft-deleted row brought it back into every read. A secondDelete
also moved the original timestamp forward and returned1rather than0.- Reads and writes that hand back the store's own tracked object. An edit you made and never submitted
was written to the database on the nextSaveChangesanywhere on that layer.
No 2.2.1 will be cut. These are documented rather than patched — a deliberate decision taken because the
2.2.x consumer base is judged to be effectively empty, not an oversight — and the upgrade to 3.0.0 is the
remedy on offer. That remedy is not available to everyone. This release targets net10.0 and
nothing else, so if you are on net48, net8.0 or net9.0 you cannot take it at all, and what
follows is a description of what you are running rather than an upgrade path. For that case the mitigations
live in your own code: there is no Dispose in 2.2.0 to call, so create as few Data Access Layer
instances as you can and keep them short-lived; drive transactions through Context.Database yourself
rather than through a Data Access Object's EnsureBeginTransaction/EnsureTransactionCommit/
EnsureTransactionRollback members; never pass a soft-deleted entity to Update; and configure
QueryTrackingBehavior.NoTracking on the context you hand in, which closes the Get half of the
fourth defect though not the Insert half.
Entity Framework 6 support is gone
The 2.2.0 package shipped two implementations chosen by target framework — EntityFramework 6.5.1 on the .NET
Framework targets and EF Core on .NET 8 and 9 — and the two did not behave alike. Most visibly, the EF6
Update was an upsert that would store a row that did not exist, while the EF Core one requires the row to
be there already. The EF6 branch has been removed outright. If you were relying on the upsert, you now need an
explicit Insert.
Target frameworks collapse to net10.0
net461, net471, net48, net80 and net90 are all gone and net10.0 is the only
target. This is deliberate rather than incidental — this library is a thin layer over EF Core, and carrying
runtimes EF Core itself no longer serves was costing more than it returned. If you are on .NET Framework, .NET 8
or .NET 9 you cannot restore this version and should remain on the 2.2.x line. Entity Framework Core moves from
9.0.4 to 10.0.11 alongside it.
ProphetsWay.BaseDataAccess moves from 2.5.0 to 3.2.0
Three changes in that dependency reach you through this one. IBaseDataAccess now extends IDisposable,
so every Data Access Layer has a Dispose and callers are expected to use one. Exceptions thrown by your
own Data Access Layer methods are no longer wrapped in TargetInvocationException on their way out of the
dispatcher — if you were catching that wrapper and unwrapping InnerException, catch the real exception type
instead. And 3.2.0 annotates that package's contracts for nullable reference types, which changes what the
compiler can tell you rather than what runs.
The annotation that reaches an ordinary caller is on IBaseDao<T>, whose Get every earlier version of
that package left null-oblivious:
// 2.5.0 and 3.1.0 — null-oblivious
T Get(T item);
// 3.2.0
T? Get(T item);Nothing about the behavior is new — a Get for a row that is not there has always come back null — but
a call through your own ICompanyDao : IBaseDao<Company> now binds Company? instead of an oblivious
Company, so a project with nullable enabled may see a CS8602 where it previously saw nothing. That is
a new warning and not a break: no signature changed, nothing you have compiled needs rebuilding, and a project
without nullable enabled sees none of it. If you implement IBaseDao<T> yourself rather than deriving from a
base in this library, read that package's own 3.2.0 entry as well — GetAll, GetPaged and
GetCount gained an annotated parameter, and an implementation declaring a plain T there is now
stricter than the interface allows and will report CS8767.
Taking 3.2.0 is also what let the last of this library's warning suppressions go. Ten
#pragma warning disable CS8766 pairs across eight files were holding down a diagnostic raised because the
bases here declared the nullable Get return their documentation described while the interface they
implemented could not say the same thing. Both sides agree now, so the suppressions are deleted rather than
replaced and no #pragma of any kind is left in the library — the compiler verifies what it was previously
being asked to ignore.
BaseNonIdDao and BaseSoftNonIdDao keep their names but are different types
This is the change most likely to be missed, because these two names do not disappear. They still resolve, so
the upgrade reads like a small refactor rather than a replacement. In 2.2.0 these were:
BaseNonIdDao<T> : IBaseDao<T> where T: class, IBaseEntity
BaseSoftNonIdDao<T> : BaseNonIdDao<T>, IBaseDao<T> where T : class, IBaseSoftEntityThey are now built on a separate plumbing class, and the members underneath you are not the members that were
there before:
BaseNonIdDao<TEntity> : RootNonIdDao<TEntity>, IBaseDao<TEntity>
BaseSoftNonIdDao<TEntity> : RootSoftNonIdDao<TEntity>, IBaseDao<TEntity>Get and Update were abstract and are now virtual with working defaults, so an existing override
keeps compiling while the code it overrides has changed underneath it. Insert and Delete were
concrete and non-virtual and are now inherited virtual members with new implementations. Context and
Dataset were public and are now protected. The public EnsureBeginTransaction,
EnsureTransactionCommit and EnsureTransactionRollback members are no longer on this surface. In
their place RootNonIdDao declares one new abstract member, MatchRow, which returns the predicate
identifying a single row — so your derived class will at least fail to compile until you supply it, which is the
one piece of this the compiler will catch for you.
The migration is to rewrite the class onto the new keyless family described below, supplying MatchRow and
dropping any overrides that no longer correspond to anything. No wrapper preserving the old shape ships in this
release, so there is nothing to fall back to and no reason to delay the rewrite.
BaseEFDataAccess takes one type parameter and is constructed differently
The published line documented BaseEFDataAccess<TContextType, TIdType>. That type no longer exists. The
identifier type parameter was never used for anything the class did, and it is gone:
BaseEFDataAccess<TContext> : BaseDataAccess.BaseDataAccess, IBaseDataAccess where TContext : DbContextThe class is now abstract, and its context constraint has been relaxed from BaseEFContext to
DbContext, so any context you already have will do. The protected Context property is typed
TContext rather than DbContext, which means your derived layer sees its own context type without a
cast.
Both public constructors are gone. BaseEFDataAccess(string connectionString) and
BaseEFDataAccess(DbContextOptions options) are replaced by a single protected constructor that takes a
built context and a statement of who owns it:
protected BaseEFDataAccess(TContext context, ContextOwnership ownership)A derived layer that called : base(connectionString) must now build the context itself — or accept one
from its caller — and say whether it is responsible for disposing it.
BaseEFContext no longer takes a connection string, and no longer picks a provider
BaseEFContext(string connectionString) has been removed; the DbContextOptions constructor is the
only one ...
3.0.0-509.Beta
v3.0.0
Not yet published — nuget.org still serves 2.2.0 as the latest version of this package. Everything below is a
change against that published 2.2.0 package.
This is a rewrite of the library on top of Entity Framework Core alone, and it breaks nearly every consumer.
Read the whole entry before upgrading. There are no compatibility wrappers and none are planned; if the
migration is not worth your afternoon, stay on 2.2.x, which continues to work exactly as it did.
Entity Framework 6 support is gone
The 2.2.0 package shipped two implementations chosen by target framework — EntityFramework 6.5.1 on the .NET
Framework targets and EF Core on .NET 8 and 9 — and the two did not behave alike. Most visibly, the EF6
Update was an upsert that would store a row that did not exist, while the EF Core one requires the row to
be there already. The EF6 branch has been removed outright. If you were relying on the upsert, you now need an
explicit Insert.
Target frameworks collapse to net10.0
net461, net471, net48, net80 and net90 are all gone and net10.0 is the only
target. This is deliberate rather than incidental — this library is a thin layer over EF Core, and carrying
runtimes EF Core itself no longer serves was costing more than it returned. If you are on .NET Framework, .NET 8
or .NET 9 you cannot restore this version and should remain on the 2.2.x line. Entity Framework Core moves from
9.0.4 to 10.0.11 alongside it.
ProphetsWay.BaseDataAccess moves from 2.5.0 to 3.2.0
Three changes in that dependency reach you through this one. IBaseDataAccess now extends IDisposable,
so every Data Access Layer has a Dispose and callers are expected to use one. Exceptions thrown by your
own Data Access Layer methods are no longer wrapped in TargetInvocationException on their way out of the
dispatcher — if you were catching that wrapper and unwrapping InnerException, catch the real exception type
instead. And 3.2.0 annotates that package's contracts for nullable reference types, which changes what the
compiler can tell you rather than what runs.
The annotation that reaches an ordinary caller is on IBaseDao<T>, whose Get every earlier version of
that package left null-oblivious:
// 2.5.0 and 3.1.0 — null-oblivious
T Get(T item);
// 3.2.0
T? Get(T item);Nothing about the behavior is new — a Get for a row that is not there has always come back null — but
a call through your own ICompanyDao : IBaseDao<Company> now binds Company? instead of an oblivious
Company, so a project with nullable enabled may see a CS8602 where it previously saw nothing. That is
a new warning and not a break: no signature changed, nothing you have compiled needs rebuilding, and a project
without nullable enabled sees none of it. If you implement IBaseDao<T> yourself rather than deriving from a
base in this library, read that package's own 3.2.0 entry as well — GetAll, GetPaged and
GetCount gained an annotated parameter, and an implementation declaring a plain T there is now
stricter than the interface allows and will report CS8767.
Taking 3.2.0 is also what let the last of this library's warning suppressions go. Ten
#pragma warning disable CS8766 pairs across eight files were holding down a diagnostic raised because the
bases here declared the nullable Get return their documentation described while the interface they
implemented could not say the same thing. Both sides agree now, so the suppressions are deleted rather than
replaced and no #pragma of any kind is left in the library — the compiler verifies what it was previously
being asked to ignore.
BaseNonIdDao and BaseSoftNonIdDao keep their names but are different types
This is the change most likely to be missed, because these two names do not disappear. They still resolve, so
the upgrade reads like a small refactor rather than a replacement. In 2.2.0 these were:
BaseNonIdDao<T> : IBaseDao<T> where T: class, IBaseEntity
BaseSoftNonIdDao<T> : BaseNonIdDao<T>, IBaseDao<T> where T : class, IBaseSoftEntityThey are now built on a separate plumbing class, and the members underneath you are not the members that were
there before:
BaseNonIdDao<TEntity> : RootNonIdDao<TEntity>, IBaseDao<TEntity>
BaseSoftNonIdDao<TEntity> : RootSoftNonIdDao<TEntity>, IBaseDao<TEntity>Get and Update were abstract and are now virtual with working defaults, so an existing override
keeps compiling while the code it overrides has changed underneath it. Insert and Delete were
concrete and non-virtual and are now inherited virtual members with new implementations. Context and
Dataset were public and are now protected. The public EnsureBeginTransaction,
EnsureTransactionCommit and EnsureTransactionRollback members are no longer on this surface. In
their place RootNonIdDao declares one new abstract member, MatchRow, which returns the predicate
identifying a single row — so your derived class will at least fail to compile until you supply it, which is the
one piece of this the compiler will catch for you.
The migration is to rewrite the class onto the new keyless family described below, supplying MatchRow and
dropping any overrides that no longer correspond to anything. No wrapper preserving the old shape ships in this
release, so there is nothing to fall back to and no reason to delay the rewrite.
BaseEFDataAccess takes one type parameter and is constructed differently
The published line documented BaseEFDataAccess<TContextType, TIdType>. That type no longer exists. The
identifier type parameter was never used for anything the class did, and it is gone:
BaseEFDataAccess<TContext> : BaseDataAccess.BaseDataAccess, IBaseDataAccess where TContext : DbContextThe class is now abstract, and its context constraint has been relaxed from BaseEFContext to
DbContext, so any context you already have will do. The protected Context property is typed
TContext rather than DbContext, which means your derived layer sees its own context type without a
cast.
Both public constructors are gone. BaseEFDataAccess(string connectionString) and
BaseEFDataAccess(DbContextOptions options) are replaced by a single protected constructor that takes a
built context and a statement of who owns it:
protected BaseEFDataAccess(TContext context, ContextOwnership ownership)A derived layer that called : base(connectionString) must now build the context itself — or accept one
from its caller — and say whether it is responsible for disposing it.
BaseEFContext no longer takes a connection string, and no longer picks a provider
BaseEFContext(string connectionString) has been removed; the DbContextOptions constructor is the
only one left. On the EF Core side that removed constructor called UseSqlServer for you, which meant the
library chose your database provider. It no longer does — whoever builds the options names the provider. This
also removes the v2.0.0 behavior where omitting a connection string produced an in-memory context; build the
options with the provider you want, in-memory included — though as the next section describes, the in-memory
provider is no longer one this package hands you. Deriving from BaseEFContext is now optional, since
BaseEFDataAccess<TContext> accepts any DbContext.
The package no longer brings a database provider with it
Installing 2.2.0 also installed Microsoft.EntityFrameworkCore.SqlServer and
Microsoft.EntityFrameworkCore.InMemory, because both were PackageReferences of the library itself.
A consumer on PostgreSQL, MySQL or SQLite restored two providers they were never going to call, and carried them
into every build and every deployment. Both are gone from this package.
Microsoft.EntityFrameworkCore 10.0.11 stays, because that is the dependency the library genuinely has.
Measured across the change, the dependency closure of a project taking this package goes from
EntityFrameworkCore, EntityFrameworkCore.SqlServer and EntityFrameworkCore.InMemory at the top
level — with EntityFrameworkCore.Relational and Microsoft.SqlServer.Server behind them — to
EntityFrameworkCore alone, behind which sit only EntityFrameworkCore.Abstractions and
EntityFrameworkCore.Analyzers. No provider of any kind, and no relational assembly, remains anywhere in
the closure.
This is a breaking change if you were calling a provider you never referenced yourself. A line such as
options.UseSqlServer(connectionString) compiled under 2.2.0 without
Microsoft.EntityFrameworkCore.SqlServer ever appearing in your project file, because this package supplied
it for you. That line will now fail to compile. The remedy is one line in your own project file:
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.11" />Name whichever provider you actually use — Npgsql.EntityFrameworkCore.PostgreSQL,
Pomelo.EntityFrameworkCore.MySql, Microsoft.EntityFrameworkCore.Sqlite, or
Microsoft.EntityFrameworkCore.InMemory if what you wanted it for was tests. Nothing else about the call
changes: no signature moved, no type was removed, and the code you already wrote keeps working the moment the
package it depends on is declared where it belongs.
This is the packaging catching up to the code rather than a change of behavior, and it is worth being precise
about which. The library has named no provider in code since the ```BaseEFContext`...
2.2.0
v2.2.0
Added support for non Id Based entities, in the BaseSoftDao class. This allows for the use of non Id based entities in the BaseSoftDao class.
This is useful for entities that do not have a Id property, such as a composite key or a key that is not an integer.
The following classes were added:
BaseNonIdDao<T> : IBaseDao<T> where T: class, IBaseEntity
BaseSoftNonIdDao<T> : BaseNonIdDao<T>, IBaseDao<T> where T : class, IBaseSoftEntitySimilarly to the other Soft Dao classes, these classes will use the SoftDelete property to mark the entity as deleted, rather than actually deleting it from the database.
You won't have to manage the Created, Updated, or Deleted dates manually unless you override the methods in the BaseDao class.
v2.1.1
Updated BaseDataAccess to use the new interface for IBaseSoftIdEntity and removed the interface from this project.
Fixed a bug where the BaseSoft Daos were not using the correct base class.
v2.1.0
Updated libraries to current versions, removed target frameworks that are end of life, and added support for .Net 8.0 and 9.0.
v2.0.0
Major updates to Entity Framework and removing obsolete methods
- added support for DbContextOptions at constructor for BaseDataAccess
- added support for non-connection string instances, will create an "in memory" instance/context (.Net 6 and above only)
- EF Tests exercise old and new .Net versions, but across both EF and EFCore as well
v1.0.1
Updated ProphetsWay.Example submodule.
Updated readme link and Licence to MIT.
v1.0.0
Initial Release!
Created a bunch of BaseDao classes to help cut down on the CRUD calls when using a proper DAL implementation with Entity Framework.
Changes:
This list of changes was auto generated.
2.1.1
v2.1.1
Updated BaseDataAccess to use the new interface for IBaseSoftIdEntity and removed the interface from this project.
Fixed a bug where the BaseSoft Daos were not using the correct base class.
v2.1.0
Updated libraries to current versions, removed target frameworks that are end of life, and added support for .Net 8.0 and 9.0.
v2.0.0
Major updates to Entity Framework and removing obsolete methods
- added support for DbContextOptions at constructor for BaseDataAccess
- added support for non-connection string instances, will create an "in memory" instance/context (.Net 6 and above only)
- EF Tests exercise old and new .Net versions, but across both EF and EFCore as well
v1.0.1
Updated ProphetsWay.Example submodule.
Updated readme link and Licence to MIT.
v1.0.0
Initial Release!
Created a bunch of BaseDao classes to help cut down on the CRUD calls when using a proper DAL implementation with Entity Framework.
Changes:
- fbddee1 fixed a bug with the base soft daos (#17)
- 4dfde9d Prophet/net framework upgrade (#16)
- bc3f34c updated project details to be included in nuget package creation (#10)
- 4776923 Prophet/context options (#9)
- 73ba862 Prophet/net50 update (#6)
This list of changes was auto generated.
2.0.0-445.Beta
v2.0.0
Major updates to Entity Framework and removing obsolete methods
- added support for DbContextOptions at constructor for BaseDataAccess
- added support for non-connection string instances, will create an "in memory" instance/context (.Net 6 only)
- EF Tests exercise old and new .Net versions, but across both EF and EFCore as well
v1.0.1
Updated ProphetsWay.Example submodule.
Updated readme link and Licence to MIT.
v1.0.0
Initial Release!
Created a bunch of BaseDao classes to help cut down on the CRUD calls when using a proper DAL implementation with Entity Framework.
Changes:
- bc3f34c updated project details to be included in nuget package creation (#10)
- 4776923 Prophet/context options (#9)
- 73ba862 Prophet/net50 update (#6)
This list of changes was auto generated.
2.0.0-442.Beta
v2.0.0
Major updates to Entity Framework and removing obsolete methods
- added support for DbContextOptions at constructor for BaseDataAccess
- added support for non-connection string instances, will create an "in memory" instance/context (.Net 6 only)
- EF Tests exercise old and new .Net versions, but across both EF and EFCore as well
v1.0.1
Updated ProphetsWay.Example submodule.
Updated readme link and Licence to MIT.
v1.0.0
Initial Release!
Created a bunch of BaseDao classes to help cut down on the CRUD calls when using a proper DAL implementation with Entity Framework.
Changes:
This list of changes was auto generated.
1.0.1
v1.0.1
Updated ProphetsWay.Example submodule.
Updated readme link and Licence to MIT.
v1.0.0
Initial Release!
Created a bunch of BaseDao classes to help cut down on the CRUD calls when using a proper DAL implementation with Entity Framework.
Changes:
This list of changes was auto generated.
1.0.0
v1.0.0
Initial Release!
Created a bunch of BaseDao classes to help cut down on the CRUD calls when using a proper DAL implementation with Entity Framework.
Changes:
- 9e6662e Merge pull request #3 from ProphetManX/prophet/updating_readme
- c78235a updated the readme
- 578e61d copied the structure of the readme from ibatistools
- ec47183 Merge pull request #1 from ProphetManX/prophet/netstandard2.0_fixes
- fe912c2 added some properties to the project for packaging and versioning
- aaf1497 added more net framework versions to the unit tests to verify that older framework versions also work
- 527176b added support for net framework targets
- e409505 added the readme and changelog to the solution.
- bf93a8c refactored the context a little, i like this better, reduces duplicate code
- 5cecade updated submodule and created a changelog
See More
- 181b38d updated all the ef code to support netstandard 2.0
- 724f021 added the new projects from the submodule
- abcffca added the foreign key column mappings in the context
- f7e248c had to order the list before i can use "skip"
- 149dab8 updated all the code so i can run the base unit tests
- f9d92e1 pulled update for submodule
- bc34c0d updated submodule
- 383e19a updated the EF instance of the DataAccess project with valid content, illustrating how a user would actually use all this code
- 519312b created a base DataAccess class for use, and a BaseEFContext class, so it ensures the context used by the BaseEFDataAccess class has a connection string constructor on it
- 00c4ba3 finished the getall dao, and created the paged dao
- 2e78802 added a base level transaction handler, so you can ensure a transaction covers a method you might be coding within a dao, and if some bigger process already has a transaction started, then it will not prematurely commit/rollback
- 031e795 stubbed out all the projects, and got two base daos coded
- 205d749 added the submodule linking to the Example repo for database and dataaccess projects
- b9588df Update README.md
This list of changes was auto generated.