diff --git a/.gitignore b/.gitignore index 63701ee..75fc91c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ packages bin obj TestResults +.nuget #include package target files which may be required for msbuild !packages/*.targets diff --git a/EntityFrameworkCoreRepository/BaseRepository.cs b/EntityFrameworkCoreRepository/BaseRepository.cs new file mode 100644 index 0000000..6f5fac0 --- /dev/null +++ b/EntityFrameworkCoreRepository/BaseRepository.cs @@ -0,0 +1,226 @@ +using EntityFramework.Repository.Core.Interfaces; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace EntityFramework.Repository.Core +{ + public abstract class BaseRepository : + IBaseRepository + , IDisposable + where T : class + where C : DbContext + { + protected C Context { get; set; } + protected Lazy> IgnoreFieldsOnUpdate = new Lazy>(); + protected Lazy>>> IgnoreFieldsOnUpdate2 = new Lazy>>>(); + + protected BaseRepository(C context) + { + Context = context; + } + + public virtual void AddUpdateIgnoreField(string fieldName) + { + IgnoreFieldsOnUpdate.Value.Add(fieldName); + } + + public virtual void AddUpdateIgnoreField(Expression> fieldName) + { + IgnoreFieldsOnUpdate2.Value.Add(fieldName); + } + + public virtual T? Find(int id) + { + return Context.Set().Find(id); + } + + public virtual T? Find(params object[] ids) + { + return Context.Set().Find(ids); + } + + public virtual async Task FindAsync(int id) + { + return await Context.Set().FindAsync(id); + } + + public virtual async Task FindAsync(params object[] ids) + { + return await Context.Set().FindAsync(ids); + } + + public virtual IQueryable FindBy(Expression> predicate) + { + return Context.Set().Where(predicate); + } + + public virtual bool Exists(Expression> predicate) + { + return Context.Set().AsNoTracking().Any(predicate); + } + + public virtual void Delete(T entity) + { + Context.Set().Remove(entity); + } + + public virtual void Delete(IEnumerable entities) + { + foreach (T entity in entities) + { + Delete(entity); + } + } + + public virtual void Reload(T entity) + { + Context.Entry(entity).Reload(); + } + + public async virtual Task ReloadAsync(T entity) + { + await Context.Entry(entity).ReloadAsync(); + } + + public virtual IQueryable FindByReadOnly(Expression> predicate) + { + return Context.Set().AsNoTracking().Where(predicate); + } + + public virtual IQueryable GetAll() + { + return Context.Set().AsNoTracking(); + } + + public virtual T Add(T entity) + { + Context.Set().Add(entity); + return entity; + } + + public virtual IEnumerable Add(IEnumerable entities) + { + Context.Set().AddRange(entities); + return entities; + } + + public virtual void Update(T entity, int id) + { + var entityToUpdate = Context.Set().Find(id); + + if (entityToUpdate == null) throw CreateEntityNotFoundException(id.ToString(), typeof(T).Name); + + Context.Entry(entityToUpdate).CurrentValues.SetValues(entity); + + MarkIgnoreFields(entityToUpdate); + } + + public virtual void Update(T entity, Expression> predicate) + { + var entityToUpdate = Context.Set().Where(predicate).SingleOrDefault(); + + if (entityToUpdate == null) throw CreateEntityNotFoundException(predicate.ToString(), typeof(T).Name); + + Context.Entry(entityToUpdate).CurrentValues.SetValues(entity); + + MarkIgnoreFields(entityToUpdate); + } + + public virtual void Update(Delta delta, params object[] ids) + { + var entityToUpdate = Context.Set().Find(ids); + + if (entityToUpdate == null) throw CreateEntityNotFoundException(ids.ToString()!, typeof(T).Name); + + foreach (string field in delta.UpdatedFields()) + { + var fieldToSet = typeof(T).GetProperty(field); + var dataOrigin = delta.Internal.GetType().GetProperty(field); + + fieldToSet!.SetValue(entityToUpdate, dataOrigin!.GetValue(delta.Internal)); + } + + MarkIgnoreFields(entityToUpdate); + } + + public void Update(Delta delta, Expression> predicate) + { + var entityToUpdate = Context.Set().Where(predicate).SingleOrDefault(); + + if (entityToUpdate == null) throw CreateEntityNotFoundException(predicate.ToString(), typeof(T).Name); + + foreach (string field in delta.UpdatedFields()) + { + var fieldToSet = typeof(T).GetProperty(field); + var dataOrigin = delta.Internal.GetType().GetProperty(field); + + fieldToSet!.SetValue(entityToUpdate, dataOrigin!.GetValue(delta.Internal)); + } + + MarkIgnoreFields(entityToUpdate); + } + + protected virtual E CreateEntityNotFoundException(string entityId, string entityType) + { + return (E)Activator.CreateInstance(typeof(E), string.Format("{0} is not a valid identity key(s) for {1}.", entityId, entityType))!; + } + + protected virtual void MarkIgnoreFields(T entityToUpdate) + { + if (IgnoreFieldsOnUpdate.IsValueCreated) + { IgnoreFieldsOnUpdate.Value.ForEach(ignoreField => Context.Entry(entityToUpdate).Property(ignoreField).IsModified = false); } + + if (IgnoreFieldsOnUpdate2.IsValueCreated) + { IgnoreFieldsOnUpdate2.Value.ForEach(ignoreField => Context.Entry(entityToUpdate).Property(ignoreField).IsModified = false); } + } + + public async virtual Task SaveAsync() + { + return await Context.SaveChangesAsync(); + } + + public virtual int Save() + { + return Context.SaveChanges(); + } + + public virtual int Count() + { + return Context.Set().Count(); + } + + public async virtual Task CountAsync() + { + return await Context.Set().CountAsync(); + } + + #region IDisposable Support + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + if (Context != null) + { + Context.Dispose(); + } + } + + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + } + #endregion + } +} diff --git a/EntityFrameworkCoreRepository/DatabaseFactory.cs b/EntityFrameworkCoreRepository/DatabaseFactory.cs new file mode 100644 index 0000000..0577bbc --- /dev/null +++ b/EntityFrameworkCoreRepository/DatabaseFactory.cs @@ -0,0 +1,26 @@ +using System; +using Microsoft.EntityFrameworkCore; + +namespace EntityFramework.Repository.Core +{ + public interface IDatabaseFactory + { + C GetNewDbContext(); + } + + public class DatabaseFactory : IDatabaseFactory + where C : DbContext + { + protected string DbConnectionString { get; set; } + + public DatabaseFactory(string connectionString) + { + DbConnectionString = connectionString; + } + + public virtual C GetNewDbContext() + { + return (C)Activator.CreateInstance(typeof(C), DbConnectionString)!; + } + } +} diff --git a/EntityFrameworkCoreRepository/Delta.cs b/EntityFrameworkCoreRepository/Delta.cs new file mode 100644 index 0000000..4935781 --- /dev/null +++ b/EntityFrameworkCoreRepository/Delta.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +namespace EntityFramework.Repository.Core +{ + public class Delta where T : class + { + List Fields { get; set; } + public T Internal { get; set; } + + public List UpdatedFields() + { + return Fields; + } + + public Delta() + { + Internal = (T)Activator.CreateInstance(typeof(T))!; + Fields = new List(); + } + + public void SetValue(string fieldName, object data) + { + var prop1 = typeof(T).GetProperty(fieldName); + if (prop1 == null) + { + throw new ArgumentException($"{fieldName} was not a property found on the object."); + } + try + { + prop1.SetValue(Internal, data); + Fields.Add(fieldName); + } + catch (ArgumentException) + { + throw; + } + } + } +} diff --git a/EntityFrameworkCoreRepository/EntityFramework.Repository.Core.csproj b/EntityFrameworkCoreRepository/EntityFramework.Repository.Core.csproj new file mode 100644 index 0000000..9f08d75 --- /dev/null +++ b/EntityFrameworkCoreRepository/EntityFramework.Repository.Core.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + EntityFramework.Repository.Core + EntityFramework.Repository.Core + enable + disable + + + + + + + diff --git a/EntityFrameworkCoreRepository/Interfaces/IBaseRepository.cs b/EntityFrameworkCoreRepository/Interfaces/IBaseRepository.cs new file mode 100644 index 0000000..db861ae --- /dev/null +++ b/EntityFrameworkCoreRepository/Interfaces/IBaseRepository.cs @@ -0,0 +1,24 @@ +using System; +using System.Linq.Expressions; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace EntityFramework.Repository.Core.Interfaces +{ + public interface IBaseRepository : + IDisposable + , IReadFunctions + , IUpdateFunctions + , IDeleteFunctions + , ICreateFunctions + , ISaveFunctions + where T : class + where C : DbContext + { + int Count(); + Task CountAsync(); + bool Exists(Expression> predicate); + void Reload(T entity); + Task ReloadAsync(T entity); + } +} diff --git a/EntityFrameworkCoreRepository/Interfaces/ICreateFunctions.cs b/EntityFrameworkCoreRepository/Interfaces/ICreateFunctions.cs new file mode 100644 index 0000000..ef4151b --- /dev/null +++ b/EntityFrameworkCoreRepository/Interfaces/ICreateFunctions.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace EntityFramework.Repository.Core.Interfaces +{ + public interface ICreateFunctions + where T : class + { + T Add(T entity); + IEnumerable Add(IEnumerable entities); + } +} diff --git a/EntityFrameworkCoreRepository/Interfaces/IDeleteFunctions.cs b/EntityFrameworkCoreRepository/Interfaces/IDeleteFunctions.cs new file mode 100644 index 0000000..d89d204 --- /dev/null +++ b/EntityFrameworkCoreRepository/Interfaces/IDeleteFunctions.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace EntityFramework.Repository.Core.Interfaces +{ + public interface IDeleteFunctions + where T : class + { + void Delete(T entity); + void Delete(IEnumerable entities); + } +} diff --git a/EntityFrameworkCoreRepository/Interfaces/IReadFunctions.cs b/EntityFrameworkCoreRepository/Interfaces/IReadFunctions.cs new file mode 100644 index 0000000..2a6a83e --- /dev/null +++ b/EntityFrameworkCoreRepository/Interfaces/IReadFunctions.cs @@ -0,0 +1,19 @@ +using System; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace EntityFramework.Repository.Core.Interfaces +{ + public interface IReadFunctions + where T : class + { + IQueryable GetAll(); + IQueryable FindBy(Expression> predicate); + IQueryable FindByReadOnly(Expression> predicate); + T? Find(int id); + T? Find(params object[] ids); + Task FindAsync(int id); + Task FindAsync(params object[] ids); + } +} diff --git a/EntityFrameworkCoreRepository/Interfaces/ISaveFunctions.cs b/EntityFrameworkCoreRepository/Interfaces/ISaveFunctions.cs new file mode 100644 index 0000000..64b7e9f --- /dev/null +++ b/EntityFrameworkCoreRepository/Interfaces/ISaveFunctions.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace EntityFramework.Repository.Core.Interfaces +{ + public interface ISaveFunctions + where T : class + { + Task SaveAsync(); + int Save(); + } +} diff --git a/EntityFrameworkCoreRepository/Interfaces/IUpdateFunctions.cs b/EntityFrameworkCoreRepository/Interfaces/IUpdateFunctions.cs new file mode 100644 index 0000000..cbb92cb --- /dev/null +++ b/EntityFrameworkCoreRepository/Interfaces/IUpdateFunctions.cs @@ -0,0 +1,16 @@ +using System; +using System.Linq.Expressions; + +namespace EntityFramework.Repository.Core.Interfaces +{ + public interface IUpdateFunctions + where T : class + { + void Update(T entity, int id); + void Update(T entity, Expression> predicate); + void Update(Delta delta, params object[] ids); + void Update(Delta delta, Expression> predicate); + void AddUpdateIgnoreField(string fieldName); + void AddUpdateIgnoreField(Expression> fieldName); + } +} diff --git a/EntityFrameworkCoreRepositoryTests/DeltaTests.cs b/EntityFrameworkCoreRepositoryTests/DeltaTests.cs new file mode 100644 index 0000000..11209b6 --- /dev/null +++ b/EntityFrameworkCoreRepositoryTests/DeltaTests.cs @@ -0,0 +1,77 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using PersistentLayerCore.Entities; +using PersistentLayerCore.Repositories; +using System; + +namespace EntityFramework.Repository.Core.Tests +{ + [TestClass] + public class DeltaTests + { + TestExampleDatabaseFactory DatabaseFactory { get; set; } = null!; + + [TestInitialize] + public void Setup() + { + DatabaseFactory = new TestExampleDatabaseFactory(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void DeltaTest1() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + var newItem = new SimpleDataEntity { Name = "Delta Test" }; + var actual = repository.Add(newItem); + repository.Save(); + + var delta1 = new Delta(); + delta1.SetValue("Name", "Delta Change Test"); + + repository.Update(delta1, newItem.Id); + + repository.Save(); + + var updatedValue = repository.Find(actual.Id); + Assert.AreEqual("Delta Change Test", updatedValue!.Name); + } + + [TestCategory("CoreRepository")] + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void DeltaTestWrongDataType1() + { + var delta1 = new Delta(); + delta1.SetValue("Name", 1); + } + + [TestCategory("CoreRepository")] + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void DeltaTestInvalidFieldName1() + { + var delta1 = new Delta(); + delta1.SetValue("NameNotRight", "Right data type"); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void DeltaTestWithPredicate() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + var newItem = new SimpleDataEntity { Name = "Delta Test" }; + var actual = repository.Add(newItem); + repository.Save(); + + var delta1 = new Delta(); + delta1.SetValue("Name", "Delta Change Test"); + + repository.Update(delta1, x => x.Id == newItem.Id); + + repository.Save(); + + var updatedValue = repository.Find(actual.Id); + Assert.AreEqual("Delta Change Test", updatedValue!.Name); + } + } +} diff --git a/EntityFrameworkCoreRepositoryTests/EntityFramework.Repository.Core.Tests.csproj b/EntityFrameworkCoreRepositoryTests/EntityFramework.Repository.Core.Tests.csproj new file mode 100644 index 0000000..9df4abf --- /dev/null +++ b/EntityFrameworkCoreRepositoryTests/EntityFramework.Repository.Core.Tests.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + EntityFramework.Repository.Core.Tests + EntityFramework.Repository.Core.Tests + enable + disable + false + + + + + + + + + + + + + + + diff --git a/EntityFrameworkCoreRepositoryTests/RepositoryCreateTests.cs b/EntityFrameworkCoreRepositoryTests/RepositoryCreateTests.cs new file mode 100644 index 0000000..10c9107 --- /dev/null +++ b/EntityFrameworkCoreRepositoryTests/RepositoryCreateTests.cs @@ -0,0 +1,77 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using PersistentLayerCore.Entities; +using PersistentLayerCore.Repositories; +using System.Collections.Generic; + +namespace EntityFramework.Repository.Core.Tests +{ + [TestClass] + public class RepositoryCreateTests + { + TestExampleDatabaseFactory DatabaseFactory { get; set; } = null!; + + [TestInitialize] + public void Setup() + { + DatabaseFactory = new TestExampleDatabaseFactory(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void InsertTestMethod() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + var newItem = new SimpleDataEntity { Name = "My Test" }; + var actual = repository.Add(newItem); + var result = repository.Save(); + + Assert.AreNotEqual(0, actual.Id); + + var actual2 = repository.Find(actual.Id); + + Assert.AreEqual("My Test", actual2!.Name); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void InsertMultipleTest() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual1 = repository.Count(); + + var newItem1 = new SimpleDataEntity { Name = "Multiple Item 1" }; + var newItem2 = new SimpleDataEntity { Name = "Multiple Item 2" }; + var newItem3 = new SimpleDataEntity { Name = "Multiple Item 3" }; + repository.Add(new List { newItem1, newItem2, newItem3 }); + repository.Save(); + + var actual2 = repository.Count(); + + Assert.AreEqual(7, actual1); + Assert.AreEqual(10, actual2); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void InsertIntoCompositeKeyTableMethod() + { + var repository = new SimpleCompositeKeyEntityRepository(DatabaseFactory); + var newItem = new SimpleCompositeKeyEntity { Id = 2, Name = "Composite Test" }; + var actual = repository.Add(newItem); + var result = repository.Save(); + + Assert.AreNotEqual(0, actual.Id); + + var actual2 = repository.Find(actual.Id, actual.Name); + + Assert.AreEqual("Composite Test", actual2!.Name); + + repository.Dispose(); + } + } +} diff --git a/EntityFrameworkCoreRepositoryTests/RepositoryDeleteTests.cs b/EntityFrameworkCoreRepositoryTests/RepositoryDeleteTests.cs new file mode 100644 index 0000000..4690354 --- /dev/null +++ b/EntityFrameworkCoreRepositoryTests/RepositoryDeleteTests.cs @@ -0,0 +1,61 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using PersistentLayerCore.Repositories; + +namespace EntityFramework.Repository.Core.Tests +{ + [TestClass] + public class RepositoryDeleteTests + { + TestExampleDatabaseFactory DatabaseFactory { get; set; } = null!; + + [TestInitialize] + public void Setup() + { + DatabaseFactory = new TestExampleDatabaseFactory(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void DeleteTestMethod() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual1 = repository.Count(); + + var itemToDelete = repository.Find(1)!; + + repository.Delete(itemToDelete); + + repository.Save(); + + var actual2 = repository.Count(); + + Assert.AreEqual(7, actual1); + Assert.AreEqual(6, actual2); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void DeleteMultipleTestMethod() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual1 = repository.Count(); + + var itemsToDelete = repository.FindBy(x => x.Id == 1 || x.Id == 2); + + repository.Delete(itemsToDelete); + + repository.Save(); + + var actual2 = repository.Count(); + + Assert.AreEqual(7, actual1); + Assert.AreEqual(5, actual2); + + repository.Dispose(); + } + } +} diff --git a/EntityFrameworkCoreRepositoryTests/RepositoryReadTests.cs b/EntityFrameworkCoreRepositoryTests/RepositoryReadTests.cs new file mode 100644 index 0000000..d8d7344 --- /dev/null +++ b/EntityFrameworkCoreRepositoryTests/RepositoryReadTests.cs @@ -0,0 +1,150 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using PersistentLayerCore.Repositories; +using System.Linq; + +namespace EntityFramework.Repository.Core.Tests +{ + [TestClass] + public class RepositoryReadTests + { + TestExampleDatabaseFactory DatabaseFactory { get; set; } = null!; + + [TestInitialize] + public void Setup() + { + DatabaseFactory = new TestExampleDatabaseFactory(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void GetAllFromSimpleDataEntitiesTable() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual = repository.GetAll(); + Assert.AreEqual(7, actual.Count()); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void CountOfSimpleDataEntitiesTable() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual = repository.Count(); + Assert.AreEqual(7, actual); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void FindTestMethod1() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual = repository.Find(1); + Assert.AreEqual("Test 1", actual!.Name); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void SelectTestMethod() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual = repository.FindBy(x => x.Id == 2).FirstOrDefault(); + Assert.AreEqual("Test 2", actual!.Name); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void FindAsyncTest() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual = repository.FindAsync(2); + Assert.AreEqual("Test 2", actual.Result!.Name); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void FindAsyncMultipleParamsTest() + { + var repository = new SimpleCompositeKeyEntityRepository(DatabaseFactory); + + var actual = repository.FindAsync(1, "Another Key"); + Assert.AreEqual("Another Key", actual.Result!.Name); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void FindByReadOnlyTest() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual = repository.FindByReadOnly(x => x.Id == 1).SingleOrDefault(); + Assert.AreEqual("Test 1", actual!.Name); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void ExistsTest() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actual = repository.Exists(x => x.Id == 1); + Assert.IsTrue(actual); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void FindAndReloadAsyncTest() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actualEntity = repository.FindAsync(2).Result!; + Assert.AreEqual("Test 2", actualEntity.Name); + + actualEntity.Name = "Test 10"; + Assert.AreEqual("Test 10", actualEntity.Name); + + repository.ReloadAsync(actualEntity).Wait(); + + Assert.AreEqual("Test 2", actualEntity.Name); + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void FindAndReloadTest() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var actualEntity = repository.Find(2)!; + Assert.AreEqual("Test 2", actualEntity.Name); + + actualEntity.Name = "Test 10"; + Assert.AreEqual("Test 10", actualEntity.Name); + + repository.Reload(actualEntity); + + Assert.AreEqual("Test 2", actualEntity.Name); + repository.Dispose(); + } + } +} diff --git a/EntityFrameworkCoreRepositoryTests/RepositoryUpdateTests.cs b/EntityFrameworkCoreRepositoryTests/RepositoryUpdateTests.cs new file mode 100644 index 0000000..6d1cc39 --- /dev/null +++ b/EntityFrameworkCoreRepositoryTests/RepositoryUpdateTests.cs @@ -0,0 +1,85 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using PersistentLayerCore.Repositories; +using System; + +namespace EntityFramework.Repository.Core.Tests +{ + [TestClass] + public class RepositoryUpdateTests + { + TestExampleDatabaseFactory DatabaseFactory { get; set; } = null!; + + [TestInitialize] + public void Setup() + { + DatabaseFactory = new TestExampleDatabaseFactory(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void UpdateTestMethod() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var itemToUpdate = repository.Find(2)!; + itemToUpdate.Name = "Updated Name"; + repository.Update(itemToUpdate, itemToUpdate.Id); + repository.Save(); + + var actual = repository.Find(2); + + Assert.AreEqual("Updated Name", actual!.Name); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void UpdateTestMethodWithIgnoreFieldFeature() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + repository.AddUpdateIgnoreField("Name"); + + var itemToUpdate = repository.Find(2)!; + itemToUpdate.Name = "Updated Name"; + repository.Update(itemToUpdate, itemToUpdate.Id); + repository.Save(); + + var actual = repository.Find(2); + + Assert.AreNotEqual("Updated Name", actual!.Name); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + public void UpdateByTestMethod() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var itemToUpdate = repository.Find(2)!; + itemToUpdate.Name = "Updated Name 2"; + repository.Update(itemToUpdate, x => x.Id == 2); + repository.Save(); + + var actual = repository.Find(2); + + Assert.AreEqual("Updated Name 2", actual!.Name); + + repository.Dispose(); + } + + [TestCategory("CoreRepository")] + [TestMethod] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public void UpdateByTestMethodIncorrectId() + { + var repository = new SimpleDataEntityRepository(DatabaseFactory); + + var itemToUpdate = repository.Find(2)!; + itemToUpdate.Name = "Updated Name 2"; + repository.Update(itemToUpdate, x => x.Id == 55); + } + } +} diff --git a/EntityFrameworkCoreRepositoryTests/SampleData/TestExampleDatabaseFactory.cs b/EntityFrameworkCoreRepositoryTests/SampleData/TestExampleDatabaseFactory.cs new file mode 100644 index 0000000..bc43fc9 --- /dev/null +++ b/EntityFrameworkCoreRepositoryTests/SampleData/TestExampleDatabaseFactory.cs @@ -0,0 +1,34 @@ +using EntityFramework.Repository.Core; +using Microsoft.EntityFrameworkCore; +using PersistentLayerCore.Contexts; +using PersistentLayerCore.Entities; +using System; + +namespace EntityFramework.Repository.Core.Tests +{ + public class TestExampleDatabaseFactory : IDatabaseFactory + { + public YourCustomDataContext GetNewDbContext() + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) + .Options; + + var context = new YourCustomDataContext(options); + + context.SimpleDataEntities.Add(new SimpleDataEntity { Id = 1, Name = "Test 1" }); + context.SimpleDataEntities.Add(new SimpleDataEntity { Id = 2, Name = "Test 2" }); + context.SimpleDataEntities.Add(new SimpleDataEntity { Id = 3, Name = "Test 3" }); + context.SimpleDataEntities.Add(new SimpleDataEntity { Id = 4, Name = "Test 4" }); + context.SimpleDataEntities.Add(new SimpleDataEntity { Id = 5, Name = "Test 5" }); + context.SimpleDataEntities.Add(new SimpleDataEntity { Id = 6, Name = "Test 6" }); + context.SimpleDataEntities.Add(new SimpleDataEntity { Id = 7, Name = "Test 7" }); + + context.SimpleCompositeKeyEntities.Add(new SimpleCompositeKeyEntity { Id = 1, Name = "Another Key" }); + + context.SaveChanges(); + + return context; + } + } +} diff --git a/EntityFrameworkRepository6.sln b/EntityFrameworkRepository6.sln index a8f3caf..d6e0c5e 100644 --- a/EntityFrameworkRepository6.sln +++ b/EntityFrameworkRepository6.sln @@ -35,54 +35,188 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework.Auditing.Te EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework.SharedRepository", "EntityFramework.SharedRepository\EntityFramework.SharedRepository.csproj", "{9D38CDB7-CCED-47DB-9A21-DD94CED623DE}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EntityFrameworkCoreRepository", "EntityFrameworkCoreRepository", "{0BAF4633-11BC-BAB2-CCFD-5E30A058E763}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework.Repository.Core", "EntityFrameworkCoreRepository\EntityFramework.Repository.Core.csproj", "{994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PersistentLayerCore", "PersistentLayerCore\PersistentLayerCore.csproj", "{7B66FF42-ED46-455B-8EC2-66DB896A6F13}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EntityFrameworkCoreRepositoryTests", "EntityFrameworkCoreRepositoryTests", "{595CF16C-F1D0-B70B-A3A1-B12AB390074D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework.Repository.Core.Tests", "EntityFrameworkCoreRepositoryTests\EntityFramework.Repository.Core.Tests.csproj", "{8A97BD93-FE27-4E8B-9E96-24A6E11AE127}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Debug|x64.ActiveCfg = Debug|Any CPU + {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Debug|x64.Build.0 = Debug|Any CPU + {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Debug|x86.ActiveCfg = Debug|Any CPU + {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Debug|x86.Build.0 = Debug|Any CPU {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Release|Any CPU.ActiveCfg = Release|Any CPU {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Release|Any CPU.Build.0 = Release|Any CPU + {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Release|x64.ActiveCfg = Release|Any CPU + {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Release|x64.Build.0 = Release|Any CPU + {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Release|x86.ActiveCfg = Release|Any CPU + {0DB0F16E-6AED-4677-9954-C9F1DD69A020}.Release|x86.Build.0 = Release|Any CPU {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Debug|x64.ActiveCfg = Debug|Any CPU + {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Debug|x64.Build.0 = Debug|Any CPU + {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Debug|x86.ActiveCfg = Debug|Any CPU + {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Debug|x86.Build.0 = Debug|Any CPU {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Release|Any CPU.ActiveCfg = Release|Any CPU {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Release|Any CPU.Build.0 = Release|Any CPU + {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Release|x64.ActiveCfg = Release|Any CPU + {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Release|x64.Build.0 = Release|Any CPU + {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Release|x86.ActiveCfg = Release|Any CPU + {2D4C3ED5-34D9-4BFC-9987-D969ED02D2F1}.Release|x86.Build.0 = Release|Any CPU {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Debug|x64.ActiveCfg = Debug|Any CPU + {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Debug|x64.Build.0 = Debug|Any CPU + {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Debug|x86.ActiveCfg = Debug|Any CPU + {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Debug|x86.Build.0 = Debug|Any CPU {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Release|Any CPU.ActiveCfg = Release|Any CPU {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Release|Any CPU.Build.0 = Release|Any CPU + {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Release|x64.ActiveCfg = Release|Any CPU + {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Release|x64.Build.0 = Release|Any CPU + {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Release|x86.ActiveCfg = Release|Any CPU + {0E1BFBEA-3C3B-4063-B301-543D07F2DE5D}.Release|x86.Build.0 = Release|Any CPU {E2231BA0-E54C-402F-B076-A1010C577E42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E2231BA0-E54C-402F-B076-A1010C577E42}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2231BA0-E54C-402F-B076-A1010C577E42}.Debug|x64.ActiveCfg = Debug|Any CPU + {E2231BA0-E54C-402F-B076-A1010C577E42}.Debug|x64.Build.0 = Debug|Any CPU + {E2231BA0-E54C-402F-B076-A1010C577E42}.Debug|x86.ActiveCfg = Debug|Any CPU + {E2231BA0-E54C-402F-B076-A1010C577E42}.Debug|x86.Build.0 = Debug|Any CPU {E2231BA0-E54C-402F-B076-A1010C577E42}.Release|Any CPU.ActiveCfg = Release|Any CPU {E2231BA0-E54C-402F-B076-A1010C577E42}.Release|Any CPU.Build.0 = Release|Any CPU + {E2231BA0-E54C-402F-B076-A1010C577E42}.Release|x64.ActiveCfg = Release|Any CPU + {E2231BA0-E54C-402F-B076-A1010C577E42}.Release|x64.Build.0 = Release|Any CPU + {E2231BA0-E54C-402F-B076-A1010C577E42}.Release|x86.ActiveCfg = Release|Any CPU + {E2231BA0-E54C-402F-B076-A1010C577E42}.Release|x86.Build.0 = Release|Any CPU {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Debug|x64.ActiveCfg = Debug|Any CPU + {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Debug|x64.Build.0 = Debug|Any CPU + {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Debug|x86.ActiveCfg = Debug|Any CPU + {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Debug|x86.Build.0 = Debug|Any CPU {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Release|Any CPU.ActiveCfg = Release|Any CPU {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Release|Any CPU.Build.0 = Release|Any CPU + {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Release|x64.ActiveCfg = Release|Any CPU + {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Release|x64.Build.0 = Release|Any CPU + {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Release|x86.ActiveCfg = Release|Any CPU + {56FCFB02-E7F9-4E74-8C7D-B412A41203CC}.Release|x86.Build.0 = Release|Any CPU {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Debug|x64.ActiveCfg = Debug|Any CPU + {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Debug|x64.Build.0 = Debug|Any CPU + {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Debug|x86.ActiveCfg = Debug|Any CPU + {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Debug|x86.Build.0 = Debug|Any CPU {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Release|Any CPU.ActiveCfg = Release|Any CPU {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Release|Any CPU.Build.0 = Release|Any CPU + {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Release|x64.ActiveCfg = Release|Any CPU + {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Release|x64.Build.0 = Release|Any CPU + {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Release|x86.ActiveCfg = Release|Any CPU + {FBFA1FE8-C52D-43FC-8F2E-6767084621F1}.Release|x86.Build.0 = Release|Any CPU {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Debug|x64.ActiveCfg = Debug|Any CPU + {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Debug|x64.Build.0 = Debug|Any CPU + {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Debug|x86.ActiveCfg = Debug|Any CPU + {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Debug|x86.Build.0 = Debug|Any CPU {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Release|Any CPU.ActiveCfg = Release|Any CPU {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Release|Any CPU.Build.0 = Release|Any CPU + {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Release|x64.ActiveCfg = Release|Any CPU + {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Release|x64.Build.0 = Release|Any CPU + {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Release|x86.ActiveCfg = Release|Any CPU + {76147A0C-3D03-4E4B-91E3-3DE5B86BC231}.Release|x86.Build.0 = Release|Any CPU {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Debug|x64.ActiveCfg = Debug|Any CPU + {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Debug|x64.Build.0 = Debug|Any CPU + {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Debug|x86.ActiveCfg = Debug|Any CPU + {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Debug|x86.Build.0 = Debug|Any CPU {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Release|Any CPU.ActiveCfg = Release|Any CPU {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Release|Any CPU.Build.0 = Release|Any CPU + {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Release|x64.ActiveCfg = Release|Any CPU + {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Release|x64.Build.0 = Release|Any CPU + {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Release|x86.ActiveCfg = Release|Any CPU + {EA0B93F9-4C12-47C3-B38D-C6D4B51AA4B0}.Release|x86.Build.0 = Release|Any CPU {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Debug|x64.ActiveCfg = Debug|Any CPU + {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Debug|x64.Build.0 = Debug|Any CPU + {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Debug|x86.ActiveCfg = Debug|Any CPU + {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Debug|x86.Build.0 = Debug|Any CPU {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Release|Any CPU.ActiveCfg = Release|Any CPU {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Release|Any CPU.Build.0 = Release|Any CPU + {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Release|x64.ActiveCfg = Release|Any CPU + {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Release|x64.Build.0 = Release|Any CPU + {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Release|x86.ActiveCfg = Release|Any CPU + {F85139D8-97FD-4DB6-8F95-31349D3D7674}.Release|x86.Build.0 = Release|Any CPU {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Debug|x64.Build.0 = Debug|Any CPU + {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Debug|x86.Build.0 = Debug|Any CPU {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Release|Any CPU.ActiveCfg = Release|Any CPU {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Release|Any CPU.Build.0 = Release|Any CPU + {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Release|x64.ActiveCfg = Release|Any CPU + {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Release|x64.Build.0 = Release|Any CPU + {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Release|x86.ActiveCfg = Release|Any CPU + {9D38CDB7-CCED-47DB-9A21-DD94CED623DE}.Release|x86.Build.0 = Release|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Debug|x64.ActiveCfg = Debug|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Debug|x64.Build.0 = Debug|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Debug|x86.ActiveCfg = Debug|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Debug|x86.Build.0 = Debug|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Release|Any CPU.Build.0 = Release|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Release|x64.ActiveCfg = Release|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Release|x64.Build.0 = Release|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Release|x86.ActiveCfg = Release|Any CPU + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F}.Release|x86.Build.0 = Release|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Debug|x64.ActiveCfg = Debug|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Debug|x64.Build.0 = Debug|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Debug|x86.ActiveCfg = Debug|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Debug|x86.Build.0 = Debug|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Release|Any CPU.Build.0 = Release|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Release|x64.ActiveCfg = Release|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Release|x64.Build.0 = Release|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Release|x86.ActiveCfg = Release|Any CPU + {7B66FF42-ED46-455B-8EC2-66DB896A6F13}.Release|x86.Build.0 = Release|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Debug|x64.ActiveCfg = Debug|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Debug|x64.Build.0 = Debug|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Debug|x86.ActiveCfg = Debug|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Debug|x86.Build.0 = Debug|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Release|Any CPU.Build.0 = Release|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Release|x64.ActiveCfg = Release|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Release|x64.Build.0 = Release|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Release|x86.ActiveCfg = Release|Any CPU + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {994C2521-14D8-4C7D-9B57-8E4A48B3FF1F} = {0BAF4633-11BC-BAB2-CCFD-5E30A058E763} + {8A97BD93-FE27-4E8B-9E96-24A6E11AE127} = {595CF16C-F1D0-B70B-A3A1-B12AB390074D} + EndGlobalSection EndGlobal diff --git a/NuGet.Config b/NuGet.Config index adfcd79..d36c71e 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -5,5 +5,6 @@ + \ No newline at end of file diff --git a/PersistentLayerCore/Contexts/YourCustomDataContext.cs b/PersistentLayerCore/Contexts/YourCustomDataContext.cs new file mode 100644 index 0000000..dcf70d5 --- /dev/null +++ b/PersistentLayerCore/Contexts/YourCustomDataContext.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; +using PersistentLayerCore.Entities; + +namespace PersistentLayerCore.Contexts +{ + public class YourCustomDataContext : DbContext + { + public DbSet SimpleDataEntities { get; set; } = null!; + public DbSet SimpleCompositeKeyEntities { get; set; } = null!; + + public YourCustomDataContext(DbContextOptions options) : base(options) { } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasKey(e => new { e.Id, e.Name }); + } + } +} diff --git a/PersistentLayerCore/Entities/PersistentEntity.cs b/PersistentLayerCore/Entities/PersistentEntity.cs new file mode 100644 index 0000000..637c2bf --- /dev/null +++ b/PersistentLayerCore/Entities/PersistentEntity.cs @@ -0,0 +1,7 @@ +namespace PersistentLayerCore.Entities +{ + public abstract class PersistentEntity + { + public int Id { get; set; } + } +} diff --git a/PersistentLayerCore/Entities/SimpleCompositeKeyEntity.cs b/PersistentLayerCore/Entities/SimpleCompositeKeyEntity.cs new file mode 100644 index 0000000..a39e9b8 --- /dev/null +++ b/PersistentLayerCore/Entities/SimpleCompositeKeyEntity.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace PersistentLayerCore.Entities +{ + public class SimpleCompositeKeyEntity + { + [Key] + [Column(Order = 1)] + public int Id { get; set; } + [Key] + [Column(Order = 2)] + public string Name { get; set; } = string.Empty; + } +} diff --git a/PersistentLayerCore/Entities/SimpleDataEntity.cs b/PersistentLayerCore/Entities/SimpleDataEntity.cs new file mode 100644 index 0000000..3fddea2 --- /dev/null +++ b/PersistentLayerCore/Entities/SimpleDataEntity.cs @@ -0,0 +1,7 @@ +namespace PersistentLayerCore.Entities +{ + public class SimpleDataEntity : PersistentEntity + { + public string Name { get; set; } = string.Empty; + } +} diff --git a/PersistentLayerCore/PersistentLayerCore.csproj b/PersistentLayerCore/PersistentLayerCore.csproj new file mode 100644 index 0000000..c6f539f --- /dev/null +++ b/PersistentLayerCore/PersistentLayerCore.csproj @@ -0,0 +1,20 @@ + + + + net8.0 + PersistentLayerCore + PersistentLayerCore + enable + disable + + + + + + + + + + + + diff --git a/PersistentLayerCore/Repositories/SimpleCompositeKeyEntityRepository.cs b/PersistentLayerCore/Repositories/SimpleCompositeKeyEntityRepository.cs new file mode 100644 index 0000000..628d92e --- /dev/null +++ b/PersistentLayerCore/Repositories/SimpleCompositeKeyEntityRepository.cs @@ -0,0 +1,18 @@ +using EntityFramework.Repository.Core; +using EntityFramework.Repository.Core.Interfaces; +using PersistentLayerCore.Contexts; +using PersistentLayerCore.Entities; + +namespace PersistentLayerCore.Repositories +{ + public interface ISimpleCompositeKeyEntityRepository : IBaseRepository + { + } + + public class SimpleCompositeKeyEntityRepository : BaseRepository, ISimpleCompositeKeyEntityRepository + { + public SimpleCompositeKeyEntityRepository(IDatabaseFactory dbFactory) : base(dbFactory.GetNewDbContext()) + { + } + } +} diff --git a/PersistentLayerCore/Repositories/SimpleDataEntityRepository.cs b/PersistentLayerCore/Repositories/SimpleDataEntityRepository.cs new file mode 100644 index 0000000..1eeed91 --- /dev/null +++ b/PersistentLayerCore/Repositories/SimpleDataEntityRepository.cs @@ -0,0 +1,18 @@ +using EntityFramework.Repository.Core; +using EntityFramework.Repository.Core.Interfaces; +using PersistentLayerCore.Contexts; +using PersistentLayerCore.Entities; + +namespace PersistentLayerCore.Repositories +{ + public interface ISimpleDataEntityRepository : IBaseRepository + { + } + + public class SimpleDataEntityRepository : BaseRepository, ISimpleDataEntityRepository + { + public SimpleDataEntityRepository(IDatabaseFactory dbFactory) : base(dbFactory.GetNewDbContext()) + { + } + } +} diff --git a/appveyor.yml b/appveyor.yml index 6e05a57..fa3c110 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,12 @@ version: 1.0.{build} -image: Visual Studio 2017 +image: Visual Studio 2022 before_build: - cmd: nuget restore +- cmd: dotnet restore EntityFrameworkCoreRepository\EntityFramework.Repository.Core.csproj +- cmd: dotnet restore PersistentLayerCore\PersistentLayerCore.csproj +- cmd: dotnet restore EntityFrameworkCoreRepositoryTests\EntityFramework.Repository.Core.Tests.csproj build: project: EntityFrameworkRepository6.sln - verbosity: minimal \ No newline at end of file + verbosity: minimal +test_script: +- cmd: dotnet test EntityFrameworkCoreRepositoryTests\EntityFramework.Repository.Core.Tests.csproj \ No newline at end of file