Compare commits

..

1 Commits
main ... test

Author SHA1 Message Date
b742ee47f8 before the api step 2024-11-10 21:56:16 +03:00
164 changed files with 5728 additions and 326 deletions

View File

@ -0,0 +1,10 @@
using System;
namespace Demo.Data.Exceptions
{
public class GroupNotFoundException : RepositoryException
{
public GroupNotFoundException(int groupId)
: base($"Группа с ID {groupId} не найдена.") { }
}
}

View File

@ -0,0 +1,9 @@
using System;
namespace Demo.Data.Exceptions
{
public class RepositoryException : Exception
{
public RepositoryException(string message) : base(message) { }
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace Demo.Data.Exceptions
{
public class UserNotFoundException : RepositoryException
{
public UserNotFoundException(Guid userGuid)
: base($"Пользователь с GUID {userGuid} не найден.") { }
}
}

View File

@ -1,15 +1,8 @@
using System; namespace Demo.domain.Models // Пространство имен для моделей
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.domain.Models
{ {
public class GroupLocalEntity public class GroupLocalEntity // Класс для локальной сущности группы
{ {
public required int Id { get; set; } public required int Id { get; set; } // Обязательное свойство для идентификатора
public required string Name { get; set; } public required string Name { get; set; } // Обязательное свойство для имени
} }
} }

View File

@ -1,17 +1,11 @@
using System; namespace Demo.domain.Models // Пространство имен для моделей
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.domain.Models
{ {
internal class PresenceLocalEntity public class PresenceLocalEntity // Класс для локальной сущности присутствия
{ {
public required Guid UserGuid { get; set; } public Guid UserGuid { get; set; } // Уникальный идентификатор пользователя (Guid)
public bool IsAttedance { get; set; } = true; public int GroupId { get; set; } // Идентификатор группы
public required DateOnly Date { get; set; } public int LessonNumber { get; set; } // Номер урока
public DateTime Date { get; set; } // Дата
public required int LessonNumber { get; set; } public bool IsAttedance { get; set; } // Признак присутствия
} }
} }

View File

@ -1,25 +1,16 @@
using System; namespace Demo.domain.Models // Пространство имен для моделей
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.domain.Models
{ {
public class UserLocalEnity : IEquatable<UserLocalEnity> public class UserLocalEnity : IEquatable<UserLocalEnity> // Класс для локальной сущности пользователя, реализующий интерфейс IEquatable
{ {
public required string FIO { get; set; } public required string FIO { get; set; } // Обязательное свойство для ФИО
public Guid Guid { get; set; } public Guid Guid { get; set; } // Свойство для уникального идентификатора
public required int GroupID { get; set; } public required int GroupID { get; set; } // Обязательное свойство для идентификатора группы
public bool Equals(UserLocalEnity? other) // Метод для сравнения двух объектов UserLocalEnity
public bool Equals(UserLocalEnity? other)
{ {
if (other == null) return false; if (other == null) return false; // Если другой объект равен null, возвращаем false
return this.Guid.Equals(other.Guid); return this.Guid.Equals(other.Guid); // Сравниваем Guid текущего и другого объекта
} }
} }
} }

View File

@ -1,23 +1,17 @@
using Demo.domain.Models; using Demo.domain.Models; // Для доступа к моделям
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Data.LocalData namespace Demo.Data.LocalData // Пространство имен для локальных данных
{ {
public static class LocalStaticData public static class LocalStaticData // Статический класс для локальных данных
{ {
public static List<GroupLocalEntity> groups => new List<GroupLocalEntity> public static List<GroupLocalEntity> groups => new List<GroupLocalEntity>
{ {
new GroupLocalEntity{ Id = 1, Name = "ИП1-21" }, new GroupLocalEntity{ Id = 1, Name = "ИП1-21" }, // Группа с идентификатором 1 и именем "ИП1-21"
new GroupLocalEntity{ Id = 2, Name = "ИП1-22" }, new GroupLocalEntity{ Id = 2, Name = "ИП1-22" }, // Группа с идентификатором 2 и именем "ИП1-22"
new GroupLocalEntity{ Id = 3, Name = "ИП1-23" }, new GroupLocalEntity{ Id = 3, Name = "ИП1-23" }, // Группа с идентификатором 3 и именем "ИП1-23"
}; };
public static List<UserLocalEnity> users => new List<UserLocalEnity> public static List<UserLocalEnity> users => new List<UserLocalEnity>
{ {
new UserLocalEnity{Guid=Guid.Parse("e6b9964d-ea9f-420a-84b9-af9633bbfab9"), FIO = "RandomFio", GroupID = 1 }, new UserLocalEnity{Guid=Guid.Parse("e6b9964d-ea9f-420a-84b9-af9633bbfab9"), FIO = "RandomFio", GroupID = 1 },
@ -27,5 +21,10 @@ namespace Demo.Data.LocalData
new UserLocalEnity{Guid=Guid.Parse("efcc1473-c116-4244-b3f7-f2341a5c3003"), FIO = "RandomFio4", GroupID = 2 }, new UserLocalEnity{Guid=Guid.Parse("efcc1473-c116-4244-b3f7-f2341a5c3003"), FIO = "RandomFio4", GroupID = 2 },
new UserLocalEnity{Guid=Guid.Parse("60640fb3-ace2-4cad-81d5-a0a58bc2dbbd"), FIO = "RandomFio5", GroupID = 3 }, new UserLocalEnity{Guid=Guid.Parse("60640fb3-ace2-4cad-81d5-a0a58bc2dbbd"), FIO = "RandomFio5", GroupID = 3 },
}; };
public static List<PresenceLocalEntity> presences => new List<PresenceLocalEntity>
{
};
} }
} }

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class GroupDao
{
public int Id { get; set; }
public required string Name { get; set; }
public IEnumerable<UserDao> Users { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class PresenceDao
{
public Guid UserGuid { get; set; }
public bool IsAttedance { get; set; } = true;
public DateOnly Date { get; set; }
public int LessonNumber { get; set; }
public UserDao UserDao { get; set; }
public int GroupId { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Data.RemoteData.RemoteDataBase.DAO
{
public class UserDao
{
public required string FIO { get; set; }
public Guid Guid { get; set; }
public required int GroupID { get; set; }
public GroupDao Group { get; set; }
}
}

View File

@ -0,0 +1,33 @@
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Microsoft.EntityFrameworkCore;
namespace Demo.Data.RemoteData.RemoteDataBase
{
public class RemoteDatabaseContext: DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql("Host=45.67.56.214;Port=5421;Username=user11;Database=user11;Password=JSZHJyg1");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<GroupDao>().HasKey(group => group.Id);
modelBuilder.Entity<GroupDao>().Property(group => group.Id).ValueGeneratedOnAdd();
modelBuilder.Entity<UserDao>().HasKey(user => user.Guid);
modelBuilder.Entity<UserDao>().Property(user => user.Guid).ValueGeneratedOnAdd();
modelBuilder.Entity<PresenceDao>().HasKey(presense => new {
presense.UserGuid,
presense.Date,
presense.IsAttedance,
presense.LessonNumber
});
}
public DbSet<GroupDao> Groups { get; set; }
public DbSet<UserDao> Users { get; set; }
public DbSet<PresenceDao> PresenceDaos { get; set; }
}
}

View File

@ -1,41 +1,51 @@
using Demo.Data.LocalData; using Demo.Data.Exceptions;
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.Data.Repository;
using Demo.domain.Models; using Demo.domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Demo.Data.Repository public class GroupRepositoryImpl : IGroupRepository
{ {
public class GroupRepositoryImpl : IGroupRepository private List<GroupLocalEntity> _groups = LocalStaticData.groups;
public GroupLocalEntity? GetGroupById(int groupId)
{ {
public bool AddGroup(GroupLocalEntity newGroup) return _groups.FirstOrDefault(g => g.Id == groupId);
{
throw new NotImplementedException();
} }
public List<GroupLocalEntity> GetAllGroup() // Метод для получения всех групп
public List<GroupLocalEntity> GetAllGroup() => _groups;
// Метод для добавления новой группы
public bool AddGroup(GroupLocalEntity group)
{ {
throw new NotImplementedException(); if (_groups.Any(g => g.Id == group.Id))
return false;
group.Id = _groups.Any() ? _groups.Max(g => g.Id) + 1 : 1;
_groups.Add(group);
return true;
} }
public List<GroupLocalEntity> GetAllGroups() => LocalStaticData.groups; // Метод для обновления существующей группы
public bool UpdateGroupById(int groupID, GroupLocalEntity updatedGroup)
public GroupLocalEntity GetGroupById(int groupID)
{ {
throw new NotImplementedException(); var existingGroup = GetGroupById(groupID);
if (existingGroup == null)
return false;
existingGroup.Name = updatedGroup.Name;
return true;
} }
public bool RemoveGroupById(int groupID) public bool RemoveGroupById(int groupID)
{ {
throw new NotImplementedException(); var existingGroup = GetGroupById(groupID);
} if (existingGroup == null)
return false;
public bool UpdateGroupById(int groupID, GroupLocalEntity updatedGroup) _groups.Remove(existingGroup);
{ return true;
throw new NotImplementedException();
}
} }
} }

View File

@ -1,9 +1,5 @@
using Demo.domain.Models; using Demo.Data.RemoteData.RemoteDataBase.DAO;
using System; using Demo.domain.Models;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Data.Repository namespace Demo.Data.Repository
{ {

View File

@ -0,0 +1,16 @@
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using System;
using System.Collections.Generic;
namespace Demo.Data.Repository
{
public interface IPresenceRepository
{
void SavePresence(List<PresenceLocalEntity> presences);
List<PresenceLocalEntity> GetPresenceByGroup(int groupId);
List<PresenceLocalEntity> GetPresenceByGroupAndDate(int groupId, DateTime date);
void MarkUserAsAbsent(Guid userGuid, int groupId, int firstLessonNumber, int lastLessonNumber);
void AddPresence(PresenceLocalEntity presence);
}
}

View File

@ -0,0 +1,18 @@
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Data.Repository
{
public interface IUserRepository
{
IEnumerable<UserLocalEnity> GetAllUsers { get; }
bool RemoveUserById(Guid userGuid);
UserLocalEnity? UpdateUser(UserLocalEnity user);
}
}

View File

@ -0,0 +1,62 @@
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo.Data.Repository
{
public class PresenceRepositoryImpl : IPresenceRepository
{
private readonly List<PresenceLocalEntity> _presences = new List<PresenceLocalEntity>();
public void SavePresence(List<PresenceLocalEntity> presences)
{
foreach (var presence in presences)
{
var existing = _presences.FirstOrDefault(p =>
p.Date == presence.Date &&
p.UserGuid == presence.UserGuid &&
p.LessonNumber == presence.LessonNumber);
if (existing == null)
{
_presences.Add(presence);
}
else
{
existing.IsAttedance = presence.IsAttedance;
}
}
}
public void AddPresence(PresenceLocalEntity presence)
{
if (presence == null) throw new ArgumentNullException(nameof(presence));
_presences.Add(presence);
}
public List<PresenceLocalEntity> GetPresenceByGroup(int groupId)
{
return _presences.Where(p => p.GroupId == groupId).ToList();
}
public List<PresenceLocalEntity> GetPresenceByGroupAndDate(int groupId, DateTime date)
{
return _presences.Where(p => p.GroupId == groupId && p.Date.Date == date.Date).ToList();
}
public void MarkUserAsAbsent(Guid userGuid, int groupId, int firstLessonNumber, int lastLessonNumber)
{
foreach (var lesson in Enumerable.Range(firstLessonNumber, lastLessonNumber - firstLessonNumber + 1))
{
var presence = _presences.FirstOrDefault(p => p.UserGuid == userGuid && p.GroupId == groupId && p.LessonNumber == lesson);
if (presence != null)
{
presence.IsAttedance = false; // Помечаем как отсутствующего
}
}
}
}
}

View File

@ -0,0 +1,71 @@
using Demo.Data.Exceptions;
using Demo.Data.LocalData;
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.Data.Repository;
using Demo.domain.Models;
using System.Collections.Generic;
using System.Linq;
public class SQLGroupRepositoryImpl : IGroupRepository
{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLGroupRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext)
{
_remoteDatabaseContext = remoteDatabaseContext;
}
// Метод для получения группы по ID
public GroupLocalEntity? GetGroupById(int groupId)
{
var groupDao = _remoteDatabaseContext.Groups.FirstOrDefault(g => g.Id == groupId);
return groupDao != null ? new GroupLocalEntity { Id = groupDao.Id, Name = groupDao.Name } : null;
}
// Метод для получения всех групп
public List<GroupLocalEntity> GetAllGroup()
{
return _remoteDatabaseContext.Groups
.Select(group => new GroupLocalEntity {
Id = group.Id,
Name = group.Name
}).ToList();
}
// Метод для добавления новой группы
public bool AddGroup(GroupLocalEntity group)
{
if (_remoteDatabaseContext.Groups.Any(g => g.Id == group.Id))
return false;
var groupDao = new GroupDao { Id = group.Id, Name = group.Name };
_remoteDatabaseContext.Groups.Add(groupDao);
_remoteDatabaseContext.SaveChanges();
return true;
}
// Метод для обновления существующей группы
public bool UpdateGroupById(int groupID, GroupLocalEntity updatedGroup)
{
var existingGroup = _remoteDatabaseContext.Groups.FirstOrDefault(g => g.Id == groupID);
if (existingGroup == null)
return false;
existingGroup.Name = updatedGroup.Name;
_remoteDatabaseContext.SaveChanges();
return true;
}
// Метод для удаления группы по ID
public bool RemoveGroupById(int groupID)
{
var existingGroup = _remoteDatabaseContext.Groups.FirstOrDefault(g => g.Id == groupID);
if (existingGroup == null)
return false;
_remoteDatabaseContext.Groups.Remove(existingGroup);
_remoteDatabaseContext.SaveChanges();
return true;
}
}

View File

@ -0,0 +1,105 @@
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
namespace Demo.Data.Repository
{
public class SQLPresenceRepositoryImpl : IPresenceRepository
{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLPresenceRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext)
{
_remoteDatabaseContext = remoteDatabaseContext;
}
public void SavePresence(List<PresenceLocalEntity> presences)
{
foreach (var presence in presences)
{
var existing = _remoteDatabaseContext.PresenceDaos.FirstOrDefault(p =>
p.Date == DateOnly.FromDateTime(presence.Date) &&
p.UserGuid == presence.UserGuid &&
p.LessonNumber == presence.LessonNumber);
if (existing == null)
{
var newPresence = new PresenceDao
{
Date = DateOnly.FromDateTime(presence.Date),
UserGuid = presence.UserGuid,
LessonNumber = presence.LessonNumber,
IsAttedance = presence.IsAttedance,
GroupId = presence.GroupId
};
_remoteDatabaseContext.PresenceDaos.Add(newPresence);
}
else
{
existing.IsAttedance = presence.IsAttedance;
}
}
}
public void AddPresence(PresenceLocalEntity presence)
{
if (presence == null) throw new ArgumentNullException(nameof(presence));
var newPresence = new PresenceDao
{
Date = DateOnly.FromDateTime(presence.Date),
UserGuid = presence.UserGuid,
LessonNumber = presence.LessonNumber,
IsAttedance = presence.IsAttedance,
GroupId = presence.GroupId // Если у вас есть это свойство
};
_remoteDatabaseContext.PresenceDaos.Add(newPresence);
}
public List<PresenceLocalEntity> GetPresenceByGroup(int groupId)
{
return _remoteDatabaseContext.PresenceDaos
.Where(p => p.GroupId == groupId)
.Select(p => new PresenceLocalEntity
{
Date = p.Date.ToDateTime(TimeOnly.MinValue),
UserGuid = p.UserGuid,
LessonNumber = p.LessonNumber,
IsAttedance = p.IsAttedance,
GroupId = p.GroupId
})
.ToList();
}
public List<PresenceLocalEntity> GetPresenceByGroupAndDate(int groupId, DateTime date)
{
return _remoteDatabaseContext.PresenceDaos
.Where(p => p.GroupId == groupId && p.Date == DateOnly.FromDateTime(date))
.Select(p => new PresenceLocalEntity
{
Date = p.Date.ToDateTime(TimeOnly.MinValue),
UserGuid = p.UserGuid,
LessonNumber = p.LessonNumber,
IsAttedance = p.IsAttedance,
GroupId = p.GroupId
})
.ToList();
}
public void MarkUserAsAbsent(Guid userGuid, int groupId, int firstLessonNumber, int lastLessonNumber)
{
foreach (var lesson in Enumerable.Range(firstLessonNumber, lastLessonNumber - firstLessonNumber + 1))
{
var presence = _remoteDatabaseContext.PresenceDaos.FirstOrDefault(p =>
p.UserGuid == userGuid &&
p.GroupId == groupId &&
p.LessonNumber == lesson);
if (presence != null)
{
presence.IsAttedance = false; // Помечаем как отсутствующего
}
}
}
}
}

View File

@ -0,0 +1,61 @@
using Demo.Data.Exceptions;
using Demo.Data.RemoteData.RemoteDataBase;
using Demo.Data.RemoteData.RemoteDataBase.DAO;
using Demo.domain.Models;
namespace Demo.Data.Repository
{
public class SQLUserRepositoryImpl : IUserRepository
{
private readonly RemoteDatabaseContext _remoteDatabaseContext;
public SQLUserRepositoryImpl(RemoteDatabaseContext remoteDatabaseContext)
{
_remoteDatabaseContext = remoteDatabaseContext;
}
// Метод для получения всех пользователей
public IEnumerable<UserLocalEnity> GetAllUsers => _remoteDatabaseContext.Users.Select(u => new UserLocalEnity
{
Guid = u.Guid,
FIO = u.FIO,
GroupID = u.GroupID
}).ToList();
// Метод для удаления пользователя по GUID
public bool RemoveUserById(Guid userGuid)
{
var user = _remoteDatabaseContext.Users.FirstOrDefault(u => u.Guid == userGuid);
if (user == null) throw new UserNotFoundException(userGuid);
_remoteDatabaseContext.Users.Remove(user); // Удаление
_remoteDatabaseContext.SaveChanges(); // Сохранение изменений в базе данных
return true;
}
// Метод для обновления данных пользователя
public UserLocalEnity? UpdateUser(UserLocalEnity user)
{
var existingUser = _remoteDatabaseContext.Users.FirstOrDefault(u => u.Guid == user.Guid);
if (existingUser == null) throw new UserNotFoundException(user.Guid);
existingUser.FIO = user.FIO;
existingUser.GroupID = user.GroupID;
_remoteDatabaseContext.SaveChanges(); // Сохранение изменений в базе данных
// Возвращаем обновленный объект UserLocalEnity
return new UserLocalEnity
{
Guid = existingUser.Guid,
FIO = existingUser.FIO,
GroupID = existingUser.GroupID
};
}
public IEnumerable<UserDao> GetAllUsersDao => _remoteDatabaseContext.Users.ToList(); // Дополнительный метод для DAO, если требуется
}
}

View File

@ -1,47 +1,41 @@
using Demo.Data.LocalData; using Demo.Data.Exceptions;
using Demo.Data.LocalData;
using Demo.domain.Models; using Demo.domain.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Data.Repository namespace Demo.Data.Repository
{ {
public class UserRepositoryImpl public class UserRepositoryImpl : IUserRepository
{ {
public UserRepositoryImpl() { private List<UserLocalEnity> _users;
GetAllUsers = LocalStaticData.users; public UserRepositoryImpl()
}
public List<UserLocalEnity> GetAllUsers
{ get; set; }
public bool RemoveUserByGuid(Guid userGuid)
{ {
UserLocalEnity? userLocal = GetAllUsers _users = LocalStaticData.users;
.Where(x => x.Guid == userGuid).FirstOrDefault();
if (userLocal == null) return false;
return GetAllUsers.Remove(userLocal);
} }
public UserLocalEnity? GetUserByGuid(Guid userGuid) { public IEnumerable<UserLocalEnity> GetAllUsers => _users;
UserLocalEnity? userLocal = GetAllUsers
.Where(x => x.Guid == userGuid).FirstOrDefault();
if (userLocal == null) return null;
return userLocal; public bool RemoveUserById(Guid userGuid) // Оставил Guid
{
var user = _users.FirstOrDefault(u => u.Guid == userGuid);
if (user == null) throw new UserNotFoundException(userGuid);
_users.Remove(user);
return true;
} }
public UserLocalEnity? UpdateUser(UserLocalEnity userUpdateLocalEnity) { public UserLocalEnity? UpdateUser(UserLocalEnity user)
UserLocalEnity? userLocal = GetAllUsers {
.Where(x => x.Guid == userUpdateLocalEnity.Guid).FirstOrDefault(); var existingUser = _users.FirstOrDefault(u => u.Guid == user.Guid);
if (userLocal == null) return null; if (existingUser == null) throw new UserNotFoundException(user.Guid);
userLocal.FIO = userUpdateLocalEnity.FIO;
userLocal.GroupID = userUpdateLocalEnity.GroupID;
return userLocal;
existingUser.FIO = user.FIO;
existingUser.GroupID = user.GroupID;
return existingUser;
} }
} }
} }

View File

@ -11,4 +11,14 @@
<Folder Include="Data\RemoteData\" /> <Folder Include="Data\RemoteData\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
</ItemGroup>
</Project> </Project>

View File

@ -1,14 +1,12 @@
using System; namespace Demo.domain.Models // Пространство имен для моделей
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.domain.Models
{ {
// Класс для представления группы
public class Group public class Group
{ {
public required int Id { get; set; } // Комментарий:
public required string Name { get; set; } // - Id: Идентификатор группы.
// - Name: Название группы.
public required int Id { get; set; } // Идентификатор группы
public required string Name { get; set; } // Название группы
} }
} }

View File

@ -1,18 +1,17 @@
using System; namespace Demo.domain.Models // Пространство имен для моделей
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.domain.Models
{ {
public class Presence public class Presence // Класс для представления присутствия пользователя в группе
{ {
// - User: Ссылка на пользователя, который присутствует.
// - GroupId: Идентификатор группы, в которой пользователь присутствует.
// - IsAttedance: Флаг, указывающий на присутствие пользователя.
// - Date: Дата присутствия.
// - LessonNumber: Номер урока, на котором присутствует пользователь.
public required User User { get; set; } // Ссылка на пользователя
public required int GroupId { get; set; } // Идентификатор группы
public bool IsAttedance { get; set; } = true; // Флаг присутствия
public required DateTime Date { get; set; } // Дата присутствия
public required User User { get; set; } public required int LessonNumber { get; set; } // Номер урока
public bool IsAttedance { get; set; } = true;
public required DateOnly Date { get; set; }
public required int LessonNumber { get; set; }
} }
} }

View File

@ -0,0 +1,6 @@
public class GroupResponse
{
public int Id { get; set; }
public string Name { get; set; }
}

View File

@ -1,16 +1,13 @@
using System; namespace Demo.domain.Models // Пространство имен для моделей
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.domain.Models
{ {
// Класс для представления пользователя
public class User public class User
{ {
public required string FIO { get; set; } // - FIO: Полное имя пользователя.
public Guid Guid { get; set; } // - Guid: Уникальный идентификатор пользователя.
// - Group: Ссылка на группу, к которой принадлежит пользователь.
public required Group Group { get; set; } public required string FIO { get; set; } // Полное имя пользователя
public Guid Guid { get; set; } // Уникальный идентификатор пользователя
public required Group Group { get; set; } // Ссылка на группу пользователя
} }
} }

View File

@ -0,0 +1,69 @@
using Demo.Data.Repository; // Для доступа к репозиториям данных
namespace Demo.Domain.UseCase
{
public class GroupAttendanceService
{
private readonly IPresenceRepository _presenceRepository;
private readonly IUserRepository _userRepository; // Добавляем репозиторий пользователей
public GroupAttendanceService(IPresenceRepository presenceRepository, IUserRepository userRepository)
{
_presenceRepository = presenceRepository;
_userRepository = userRepository; // Инициализируем репозиторий пользователей
}
public void DisplayGroupAttendanceInfo(int groupId)
{
// Получаем данные о посещаемости для группы с ID groupId
var presences = _presenceRepository.GetPresenceByGroup(groupId);
// Проверяем, есть ли данные о посещаемости для группы
if (presences == null || !presences.Any())
{
Console.WriteLine("Нет данных о посещаемости для группы с ID: " + groupId);
return;
}
// Вычисление количества студентов
var totalStudents = presences.Select(p => p.UserGuid).Distinct().Count(); // Предполагается, что в PresenceLocalEntity есть UserGuid
var totalSessions = presences.Select(p => p.Date).Distinct().Count();// Вычисление количества проведенных занятий
var totalAttendance = presences.Count(p => p.IsAttedance);// Общее количество присутствий
// Общий процент посещаемости
double overallAttendancePercentage = totalSessions > 0 ? (double)totalAttendance / (totalSessions * totalStudents) * 100 : 0;
Console.WriteLine($"Группа ID: {groupId}");
Console.WriteLine($"Количество студентов: {totalStudents}");
Console.WriteLine($"Количество проведенных занятий: {totalSessions}");
Console.WriteLine($"Общий процент посещаемости: {overallAttendancePercentage:F2}%");
Console.WriteLine("Студенты:");
// Вывод информации по каждому студенту
var studentAttendances = presences.GroupBy(p => p.UserGuid).Select(g => new
{
StudentName = GetStudentNameByGuid(g.Key), // Получение имени студента по его GUID
AttendedCount = g.Count(p => p.IsAttedance), // Подсчет количества посещений
MissedCount = g.Count(p => !p.IsAttedance) // Подсчет количества пропусков
});
foreach (var student in studentAttendances)
{
// Процент посещаемости студента
double attendancePercentage = totalSessions > 0
? (double)student.AttendedCount / totalSessions * 100
: 0;
var attendanceColor = attendancePercentage < 40 ? "\u001b[31m" : "\u001b[0m"; // Красный для низкого процента
Console.WriteLine($"{attendanceColor}{student.StudentName} - Посещено: {student.AttendedCount}, Пропущено: {student.MissedCount}, Процент посещаемости: {attendancePercentage:F2}%\u001b[0m");
}
}
// Метод для получения имени студента по его GUID
private string GetStudentNameByGuid(Guid userGuid)
{
var user = _userRepository.GetAllUsers.FirstOrDefault(u => u.Guid == userGuid);
return user != null ? user.FIO : "Неизвестный студент"; // Возвращаем имя студента или "Неизвестный студент"
}
}
}

View File

@ -1,45 +1,133 @@
using Demo.Data.Repository; using Demo.Data.LocalData;
using Demo.Data.Repository;
using Demo.domain.Models; using Demo.domain.Models;
using System; using Demo.domain.Models.RequestModels;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Domain.UseCase namespace Demo.Domain.UseCase
{ {
internal class GroupUseCase public class GroupUseCase
{ {
private readonly GroupRepositoryImpl _repositoryGroupImpl; private readonly IGroupRepository _repositoryGroupImpl;
public GroupUseCase(GroupRepositoryImpl repositoryGroupImpl) public GroupUseCase(IGroupRepository repositoryGroupImpl)
{ {
_repositoryGroupImpl = repositoryGroupImpl; _repositoryGroupImpl = repositoryGroupImpl;
} }
// Вывести все группы // Приватный метод для валидации имени группы
private void ValidateGroupName(string groupName)
{
if (string.IsNullOrWhiteSpace(groupName))
{
throw new ArgumentException("Имя группы не может быть пустым.");
}
}
private void ValidateGroupId(int GroupId)
{
if (GroupId < 1)
{
throw new ArgumentException("Введите корректный ID группы.");
}
}
// Приватный метод для валидации существования группы по ID
private GroupLocalEntity ValidateGroupExistence(int groupId)
{
var existingGroup = _repositoryGroupImpl.GetAllGroup().FirstOrDefault(g => g.Id == groupId);
if (existingGroup == null)
{
throw new ArgumentException("Группа не найдена.");
}
return existingGroup;
}
// Метод для получения списка всех групп
public List<Group> GetAllGroups() public List<Group> GetAllGroups()
{ {
return _repositoryGroupImpl.GetAllGroups().Select(it => new Group { Id = it.Id, Name = it.Name }).ToList(); return [.. _repositoryGroupImpl.GetAllGroup().Select(it => new Group { Id = it.Id, Name = it.Name })];
} }
// Создать новую группу
public void FindGroupById(int IdGroup)
{
List<Group> GetAllGroups()
{
return [.. _repositoryGroupImpl.GetAllGroup().Select(
it => new Group
{ Id = it.Id, Name = it.Name }
)
];
}
foreach (var group in GetAllGroups())
{
if (IdGroup == group.Id)
{
Console.WriteLine($"ID группы: {group.Id} Название группы: {group.Name}");
}
}
}
// Метод для добавления новой группы
public void AddGroup(string groupName) public void AddGroup(string groupName)
{ {
var newId = _repositoryGroupImpl.GetAllGroups().Max(g => g.Id) + 1; ValidateGroupName(groupName);
var newId = _repositoryGroupImpl.GetAllGroup().Any() ? _repositoryGroupImpl.GetAllGroup().Max(g => g.Id) + 1 : 1;
GroupLocalEntity newGroup = new GroupLocalEntity GroupLocalEntity newGroup = new GroupLocalEntity
{ {
Id = newId, Id = newId,
Name = groupName Name = groupName
}; };
_repositoryGroupImpl.AddGroup(newGroup); _repositoryGroupImpl.AddGroup(newGroup);
} }
// Изменить название группы по ID public void RemoveGroupById(int groupId)
{
ValidateGroupId(groupId);
var existingGroup = ValidateGroupExistence(groupId);
List<Group> _groups = GetAllGroups();
// Находим группу по ID и удаляем ее
var groupToRemove = _groups.FirstOrDefault(g => g.Id == existingGroup.Id);
if (groupToRemove != null)
{
_groups.Remove(groupToRemove);
_repositoryGroupImpl.RemoveGroupById(existingGroup.Id);
}
else
{
throw new ArgumentException("Группа не найдена.");
// Обработка случая, если группа не найдена (например, выброс исключения)
}
}
// Метод для изменения названия группы
public void UpdateGroup(int groupId, string newGroupName) public void UpdateGroup(int groupId, string newGroupName)
{ {
GroupLocalEntity existingGroup = _repositoryGroupImpl.GetAllGroups().FirstOrDefault(g => g.Id == groupId); ValidateGroupName(newGroupName);
var existingGroup = ValidateGroupExistence(groupId);
existingGroup.Name = newGroupName; existingGroup.Name = newGroupName;
_repositoryGroupImpl.UpdateGroup(existingGroup); _repositoryGroupImpl.UpdateGroupById(existingGroup.Id, existingGroup);
}
public List<GroupResponse> getAllGroup()
{
return _repository.GetAllGroup().Select(Group => new GroupResponse
{
Id = Group.Id,
Name = Group.Name,
}
).ToList();
} }
} }
} }

View File

@ -0,0 +1,78 @@
using Demo.Data.Repository;
using Demo.domain.Models;
namespace Demo.Domain.UseCase
{
public class UseCaseGeneratePresence
{
public readonly IUserRepository _userRepository;
public readonly IPresenceRepository _presenceRepository;
public List<PresenceLocalEntity> GetPresenceByDateAndGroup(int groupId, DateTime date)
{
return _presenceRepository.GetPresenceByGroupAndDate(groupId, date);
}
public UseCaseGeneratePresence(IUserRepository userRepository, IPresenceRepository presenceRepository)
{
_userRepository = userRepository;
_presenceRepository = presenceRepository;
}
public void GeneratePresenceDaily(int firstLesson, int lastLesson, int groupId, DateTime currentDate)
{
var users = _userRepository.GetAllUsers.Where(u => u.GroupID == groupId).ToList();
List<PresenceLocalEntity> presences = new List<PresenceLocalEntity>();
for (int lessonNumber = firstLesson; lessonNumber <= lastLesson; lessonNumber++)
{
foreach (var user in users)
{
presences.Add(new PresenceLocalEntity
{
UserGuid = user.Guid,
GroupId = user.GroupID,
Date = currentDate,
LessonNumber = lessonNumber,
IsAttedance = true
});
}
_presenceRepository.SavePresence(presences);
}
}
public void GenerateWeeklyPresence(int firstLesson, int lastLesson, int groupId, DateTime startTime)
{
for (int i = 0; i < 7; i++)
{
DateTime currentTime = startTime.AddDays(i);
GeneratePresenceDaily(firstLesson, lastLesson, groupId, currentTime);
}
}
// Отметить пользователя как отсутствующего на диапазоне занятий
public void MarkUserAbsentForLessons(Guid userGuid, int groupId, int firstLesson, int lastLesson, DateTime date)
{
var presences = _presenceRepository.GetPresenceByGroupAndDate(groupId, date);
foreach (var presence in presences.Where(p => p.UserGuid == userGuid && p.LessonNumber >= firstLesson && p.LessonNumber <= lastLesson))
{
presence.IsAttedance = false;
}
_presenceRepository.SavePresence(presences);
}
// Возвращаем список объектов PresenceLocalEntity на основе groupId
public List<PresenceLocalEntity> GetAllPresenceByGroup(int groupId)
{
return _presenceRepository.GetPresenceByGroup(groupId);
}
}
}

View File

@ -1,27 +1,58 @@
using Demo.Data.Repository; using Demo.Data.Exceptions;
using Demo.Data.Repository;
using Demo.domain.Models; using Demo.domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.Domain.UseCase namespace Demo.Domain.UseCase
{ {
public class UserUseCase public class UserUseCase
{ {
private readonly UserRepositoryImpl _repositoryUserImpl; private readonly IUserRepository _repositoryUserImpl;
private readonly IGroupRepository _repositoryGroupImpl; private readonly IGroupRepository _repositoryGroupImpl;
public UserUseCase(UserRepositoryImpl repositoryImpl, IGroupRepository repositoryGroupImpl) public UserUseCase(IUserRepository repositoryImpl, IGroupRepository repositoryGroupImpl)
{ {
_repositoryUserImpl = repositoryImpl; _repositoryUserImpl = repositoryImpl;
_repositoryGroupImpl = repositoryGroupImpl; _repositoryGroupImpl = repositoryGroupImpl;
} }
private List<Group> GetAllGroups() => _repositoryGroupImpl.GetAllGroup() // Приватный метод для валидации ФИО пользователя
.Select(it => new Group { Id = it.Id, Name = it.Name }).ToList(); private void ValidateUserFIO(string fio)
{
if (string.IsNullOrWhiteSpace(fio))
{
throw new ArgumentException("ФИО не может быть пустым.");
}
}
// Приватный метод для валидации существования пользователя по ID
private UserLocalEnity ValidateUserExistence(Guid userGuid)
{
var user = _repositoryUserImpl.GetAllUsers
.FirstOrDefault(u => u.Guid == userGuid);
if (user == null)
{
throw new Exception("Пользователь не найден.");
}
return user;
}
// Приватный метод для валидации существования группы по ID
private GroupLocalEntity ValidateGroupExistence(int groupId)
{
var group = _repositoryGroupImpl.GetAllGroup()
.FirstOrDefault(g => g.Id == groupId);
if (group == null)
{
throw new Exception("Группа не найдена.");
}
return group;
}
// Вывести всех пользователей
public List<User> GetAllUsers() => _repositoryUserImpl.GetAllUsers public List<User> GetAllUsers() => _repositoryUserImpl.GetAllUsers
.Join(_repositoryGroupImpl.GetAllGroup(), .Join(_repositoryGroupImpl.GetAllGroup(),
user => user.GroupID, user => user.GroupID,
@ -32,44 +63,66 @@ namespace Demo.Domain.UseCase
FIO = user.FIO, FIO = user.FIO,
Guid = user.Guid, Guid = user.Guid,
Group = new Group { Id = group.Id, Name = group.Name } Group = new Group { Id = group.Id, Name = group.Name }
} }).ToList();
).ToList();
// удалить пользователя по Giud // Удалить пользователя по id
public bool RemoveUserByGuid(Guid userGuid) public bool RemoveUserById(Guid userGuid)
{ {
return _repositoryUserImpl.RemoveUserByGuid(userGuid); try
{
return _repositoryUserImpl.RemoveUserById(userGuid);
}
catch (UserNotFoundException ex)
{
Console.WriteLine($"Ошибка: {ex.Message}");
return false;
}
catch (RepositoryException ex)
{
Console.WriteLine($"Ошибка в репозитории: {ex.Message}");
return false;
}
} }
// Обновить пользователя по guid
// Обновить пользователя по Guid
public User UpdateUser(User user) public User UpdateUser(User user)
{ {
UserLocalEnity userLocalEnity = new UserLocalEnity { FIO = user.FIO, GroupID = user.Group.Id, Guid = user.Guid }; ValidateUserFIO(user.FIO);
ValidateGroupExistence(user.Group.Id);
UserLocalEnity userLocalEnity = new UserLocalEnity
{
FIO = user.FIO,
GroupID = user.Group.Id,
Guid = user.Guid
};
UserLocalEnity? result = _repositoryUserImpl.UpdateUser(userLocalEnity); UserLocalEnity? result = _repositoryUserImpl.UpdateUser(userLocalEnity);
if (result == null) if (result == null)
{ {
throw new Exception(""); throw new Exception("Ошибка при обновлении пользователя.");
} }
Group? group = GetAllGroups().FirstOrDefault(it => it.Id == result!.GroupID);
if (group == null) var groupEntity = ValidateGroupExistence(result.GroupID);
return new User
{ {
throw new Exception(""); FIO = result.FIO,
} Guid = result.Guid,
return new User { FIO = user.FIO, Guid = user.Guid, Group = group }; Group = new Group
}
// Найти пользователя по Guid
public User FindUserByGuid(Guid userGuid)
{ {
var user = _repositoryUserImpl.GetAllUsers Id = groupEntity.Id,
.FirstOrDefault(u => u.Guid == userGuid); Name = groupEntity.Name
if (user == null) throw new Exception("Пользователь не найден"); }
};
}
var group = _repositoryGroupImpl.GetAllGroup() // Найти пользователя по id
.FirstOrDefault(g => g.Id == user.GroupID); public User FindUserById(Guid userGuid)
{
var user = ValidateUserExistence(userGuid);
var group = ValidateGroupExistence(user.GroupID);
return new User return new User
{ {
@ -78,7 +131,5 @@ namespace Demo.Domain.UseCase
Group = new Group { Id = group.Id, Name = group.Name } Group = new Group { Id = group.Id, Name = group.Name }
}; };
} }
//public List<Group> GetAllGroups() => _repositoryGroupImpl.GetAllGroups().Select(it => new Group { Id = it.Id, Name = it.Name }).ToList();
} }
} }

View File

@ -0,0 +1,121 @@
// <auto-generated />
using System;
using Demo.Data.RemoteData.RemoteDataBase;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Demo.Migrations
{
[DbContext(typeof(RemoteDatabaseContext))]
[Migration("20241031103935_InitialCrete")]
partial class InitialCrete
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Groups");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
{
b.Property<Guid>("UserGuid")
.HasColumnType("uuid");
b.Property<DateOnly>("Date")
.HasColumnType("date");
b.Property<bool>("IsAttedance")
.HasColumnType("boolean");
b.Property<int>("LessonNumber")
.HasColumnType("integer");
b.Property<int>("GroupId")
.HasColumnType("integer");
b.Property<Guid>("UserDaoGuid")
.HasColumnType("uuid");
b.HasKey("UserGuid", "Date", "IsAttedance", "LessonNumber");
b.HasIndex("UserDaoGuid");
b.ToTable("PresenceDaos");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
{
b.Property<Guid>("Guid")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<int>("GroupID")
.HasColumnType("integer");
b.HasKey("Guid");
b.HasIndex("GroupID");
b.ToTable("Users");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
{
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", "UserDao")
.WithMany()
.HasForeignKey("UserDaoGuid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("UserDao");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
{
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", "Group")
.WithMany("Users")
.HasForeignKey("GroupID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Group");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", b =>
{
b.Navigation("Users");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,93 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Demo.Migrations
{
/// <inheritdoc />
public partial class InitialCrete : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Groups",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Groups", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Guid = table.Column<Guid>(type: "uuid", nullable: false),
FIO = table.Column<string>(type: "text", nullable: false),
GroupID = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Guid);
table.ForeignKey(
name: "FK_Users_Groups_GroupID",
column: x => x.GroupID,
principalTable: "Groups",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "PresenceDaos",
columns: table => new
{
UserGuid = table.Column<Guid>(type: "uuid", nullable: false),
IsAttedance = table.Column<bool>(type: "boolean", nullable: false),
Date = table.Column<DateOnly>(type: "date", nullable: false),
LessonNumber = table.Column<int>(type: "integer", nullable: false),
UserDaoGuid = table.Column<Guid>(type: "uuid", nullable: false),
GroupId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PresenceDaos", x => new { x.UserGuid, x.Date, x.IsAttedance, x.LessonNumber });
table.ForeignKey(
name: "FK_PresenceDaos_Users_UserDaoGuid",
column: x => x.UserDaoGuid,
principalTable: "Users",
principalColumn: "Guid",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_PresenceDaos_UserDaoGuid",
table: "PresenceDaos",
column: "UserDaoGuid");
migrationBuilder.CreateIndex(
name: "IX_Users_GroupID",
table: "Users",
column: "GroupID");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "PresenceDaos");
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "Groups");
}
}
}

View File

@ -0,0 +1,118 @@
// <auto-generated />
using System;
using Demo.Data.RemoteData.RemoteDataBase;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Demo.Migrations
{
[DbContext(typeof(RemoteDatabaseContext))]
partial class RemoteDatabaseContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Groups");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
{
b.Property<Guid>("UserGuid")
.HasColumnType("uuid");
b.Property<DateOnly>("Date")
.HasColumnType("date");
b.Property<bool>("IsAttedance")
.HasColumnType("boolean");
b.Property<int>("LessonNumber")
.HasColumnType("integer");
b.Property<int>("GroupId")
.HasColumnType("integer");
b.Property<Guid>("UserDaoGuid")
.HasColumnType("uuid");
b.HasKey("UserGuid", "Date", "IsAttedance", "LessonNumber");
b.HasIndex("UserDaoGuid");
b.ToTable("PresenceDaos");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
{
b.Property<Guid>("Guid")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("text");
b.Property<int>("GroupID")
.HasColumnType("integer");
b.HasKey("Guid");
b.HasIndex("GroupID");
b.ToTable("Users");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.PresenceDao", b =>
{
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", "UserDao")
.WithMany()
.HasForeignKey("UserDaoGuid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("UserDao");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.UserDao", b =>
{
b.HasOne("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", "Group")
.WithMany("Users")
.HasForeignKey("GroupID")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Group");
});
modelBuilder.Entity("Demo.Data.RemoteData.RemoteDataBase.DAO.GroupDao", b =>
{
b.Navigation("Users");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,13 +1,34 @@
 using Demo.Data.RemoteData.RemoteDataBase; // Подключаем необходимые пространства имен
using Demo.Data.Repository; using Demo.Data.Repository;
using Demo.Domain.UseCase; using Demo.Domain.UseCase;
using Demo.UI; using Demo.UI;
using Microsoft.Extensions.DependencyInjection;
// Создаем экземпляр репозиториев
IServiceCollection services = new ServiceCollection(); // Создаем коллекцию сервисов
// Добавляем контекст базы данных
services.AddDbContext<RemoteDatabaseContext>();
GroupRepositoryImpl groupRepositoryImpl = new GroupRepositoryImpl(); // Добавляем репозитории
UserRepositoryImpl userRepositoryImpl = new UserRepositoryImpl(); services.AddSingleton<IGroupRepository, SQLGroupRepositoryImpl>();
UserUseCase userUseCase = new UserUseCase(userRepositoryImpl, groupRepositoryImpl); services.AddSingleton<IUserRepository, SQLUserRepositoryImpl>();
GroupUseCase groupUseCase = new GroupUseCase(groupRepositoryImpl); services.AddSingleton<IPresenceRepository, SQLPresenceRepositoryImpl>();
MainMenuUI mainMenuUI = new MainMenuUI(userUseCase, groupUseCase); // Добавляем юз-кейсы
services.AddSingleton<UserUseCase>();
services.AddSingleton<GroupUseCase>();
services.AddSingleton<UseCaseGeneratePresence>();
// Добавляем пользовательские интерфейсы
services.AddSingleton<GroupConsoleUI>();
services.AddSingleton<PresenceConsole>();
services.AddSingleton<MainMenuUI>();
var serviceProvider = services.BuildServiceProvider(); // Создаем провайдер сервисов
// Создаем пользовательский интерфейс
MainMenuUI mainMenuUI = serviceProvider.GetService<MainMenuUI>();
// Выводим главное меню
mainMenuUI.DisplayMenu(); // Выводим меню

View File

@ -1,41 +1,64 @@
using Demo.Domain.UseCase; using Demo.Domain.UseCase;
using Demo.domain.Models;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Text.RegularExpressions;
namespace Demo.UI namespace Demo.UI
{ {
internal class GroupConsoleUI public class GroupConsoleUI
{ {
GroupUseCase _groupUseCase; private readonly GroupUseCase _groupUseCase;
public GroupConsoleUI(GroupUseCase groupUseCase) public GroupConsoleUI(GroupUseCase groupUseCase)
{ {
_groupUseCase = groupUseCase; _groupUseCase = groupUseCase;
} }
public void FindGroupById(int IdGroup)
{
_groupUseCase.FindGroupById(IdGroup);
}
public void AllGroups() // Метод для отображения всех групп
public void DisplayAllGroups()
{ {
foreach (var Group in _groupUseCase.GetAllGroups()) Console.WriteLine("\n=== Список всех групп ===");
StringBuilder groupOutput = new StringBuilder();
foreach (var group in _groupUseCase.GetAllGroups())
{ {
Console.WriteLine($"{Group.Id}\t{Group.Name}"); groupOutput.AppendLine($"{group.Id}\t{group.Name}");
}
Console.WriteLine(groupOutput);
Console.WriteLine("===========================\n");
}
// Метод для добавления новой группы
public void AddGroup(string groupName)
{
try
{
_groupUseCase.AddGroup(groupName);
Console.WriteLine($"\nГруппа {groupName} добавлена.\n");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка: {ex.Message}\n");
} }
} }
public void CreateGroup(string NameGroup) public void RemoveGroup(string groupIdStr)
{ {
_groupUseCase.AddGroup(NameGroup); int groupId = int.Parse(groupIdStr);
_groupUseCase.RemoveGroupById(groupId);
Console.WriteLine($"Группа с ID: {groupId} удалена");
} }
public void UpdateNameGroup(int id, string name) // Метод для обновления названия группы
public void UpdateGroupName(int groupId, string newGroupName)
{ {
_groupUseCase.UpdateGroup(id, name); _groupUseCase.UpdateGroup(groupId, newGroupName);
Console.WriteLine($"\nНазвание группы с ID {groupId} изменено на {newGroupName}.\n");
} }
} }
} }

View File

@ -1,85 +1,225 @@
using Demo.domain.Models; using Demo.Domain.UseCase;
using Demo.Domain.UseCase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo.UI namespace Demo.UI
{ {
public class MainMenuUI public class MainMenuUI
{ {
private readonly UserConsoleUI _userConsoleUI;
private readonly GroupConsoleUI _groupConsoleUI;
private readonly PresenceConsole _presenceConsoleUI;
UserConsoleUI _userConsoleUI; public MainMenuUI(UserUseCase userUseCase, GroupUseCase groupUseCase, UseCaseGeneratePresence presenceUseCase)
GroupConsoleUI _groupConsoleUI;
public MainMenuUI(UserUseCase userUseCase, GroupUseCase groupUseCase)
{ {
_userConsoleUI = new UserConsoleUI(userUseCase); _userConsoleUI = new UserConsoleUI(userUseCase);
_groupConsoleUI = new GroupConsoleUI(groupUseCase); _groupConsoleUI = new GroupConsoleUI(groupUseCase);
DisplayMenu(); _presenceConsoleUI = new PresenceConsole(presenceUseCase);
} }
private void DisplayMenu() { public void DisplayMenu()
{
Console.WriteLine("Начало работы");
while (true) while (true)
{ {
Console.WriteLine("УПРАВЛЕНИЕ ПОЛЬЗОВАТЕЛЯМИ");
Console.WriteLine("1. Показать список всех пользователей");
Console.WriteLine("2. Удалить пользователя по его ID");
Console.WriteLine("3. Обновить данные пользователя по ID");
Console.WriteLine("4. Найти пользователя по его ID");
Console.WriteLine();
Console.WriteLine("УПРАВЛЕНИЕ ГРУППАМИ");
Console.WriteLine("5. Показать список всех групп");
Console.WriteLine("6. Создать новую группу");
Console.WriteLine("7. Удалить группу по ID");
Console.WriteLine("8. Изменить название существующей группы");
Console.WriteLine("9. Найти группу по ее ID");
Console.WriteLine();
Console.WriteLine("УПРАВЛЕНИЕ ПОСЕЩАЕМОСТЬЮ");
Console.WriteLine("10. Сгенерировать посещаемость на текущий день");
Console.WriteLine("11. Сгенерировать посещаемость на текущую неделю");
Console.WriteLine("12. Показать посещаемость всех пользователей");
Console.WriteLine("13. Отметить пользователя как отсутствующего");
Console.WriteLine("14. Вывести посещаемость группы по ID");
Console.WriteLine();
Console.WriteLine("0. Выход из программы");
Console.WriteLine();
Console.WriteLine();
Console.Write("Выберите команду: ");
string command = Console.ReadLine();
Console.WriteLine();
Console.WriteLine("1 - Вывести всех пользователей"); switch (command)
Console.WriteLine("2 - Удалить пользователя по guid");
Console.WriteLine("3 - Обновить пользователя по guid");
Console.WriteLine("4 - Найти пользователя по guid");
Console.WriteLine("5 - Вывести все группы");
Console.WriteLine("6 - Добавить группу");
Console.WriteLine("7 - Изменить название группы");
Console.Write("Введите номер команды: ");
switch (Convert.ToInt32(Console.ReadLine()))
{ {
// вывести всех пользователей case "1":
case 1: _userConsoleUI.DisplayAllUsers(); break; // Отображение всех пользователей
_userConsoleUI.DisplayAllUsers();
// удалить пользователя по guid
case 2:
Console.Write("Введите guid пользователя: ");
_userConsoleUI.RemoveUserByGuid(Guid.Parse(Console.ReadLine()));
break; break;
// обновить пользователя по guid case "2":
case 3: // Удаление пользователя по ID
Console.Write("Введите GUID пользователя для обновления: "); Console.Write("Введите ID пользователя для удаления: ");
_userConsoleUI.UpdateUserGuid(Guid.Parse(Console.ReadLine())); string inputGuid = Console.ReadLine();
if (Guid.TryParse(inputGuid, out Guid userGuid))
{
_userConsoleUI.RemoveUserById(userGuid);
}
else
{
Console.WriteLine("Неверный формат ID");
}
break; break;
// найти пользователя по guid case "3":
case 4: // Обновление пользователя по ID
Console.Write("Введите GUID пользователя: "); Console.Write("Введите ID пользователя для обновления: ");
_userConsoleUI.GetUserByGuid(Guid.Parse(Console.ReadLine())); break; string updateGuidInput = Console.ReadLine();
if (Guid.TryParse(updateGuidInput, out Guid updateUserGuid))
{
_userConsoleUI.UpdateUserById(updateUserGuid);
}
else
{
Console.WriteLine("Неверный формат ID");
}
break;
// вывести все группы case "4":
case 5: _groupConsoleUI.AllGroups(); break; // Поиск пользователя по ID
Console.Write("Введите ID пользователя для поиска: ");
string findGuidInput = Console.ReadLine();
if (Guid.TryParse(findGuidInput, out Guid findUserGuid))
{
_userConsoleUI.FindUserById(findUserGuid);
}
else
{
Console.WriteLine("Неверный формат ID");
}
break;
// добавить группу case "5":
case 6: // Отображение всех групп
_groupConsoleUI.DisplayAllGroups();
break;
case "6":
// Добавление новой группы
Console.Write("Введите название новой группы: "); Console.Write("Введите название новой группы: ");
_groupConsoleUI.CreateGroup(Console.ReadLine()); break; string newGroupName = Console.ReadLine();
_groupConsoleUI.AddGroup(newGroupName);
// изменить название группы
case 7:
Console.Write("Введите ID группы: ");
int id = Convert.ToInt32(Console.ReadLine());
Console.Write("Введи новое название: ");
string name = Console.ReadLine();
_groupConsoleUI.UpdateNameGroup(id, name);
break; break;
default: DisplayMenu(); case "7":
// Удаление группы
Console.Write("Введите ID группы для удаления: ");
string groupIdForDelete = Console.ReadLine();
_groupConsoleUI.RemoveGroup(groupIdForDelete);
break;
case "8":
// Изменение названия группы
Console.Write("Введите ID группы для изменения: ");
if (int.TryParse(Console.ReadLine(), out int groupId))
{
Console.Write("Введите новое название группы: ");
string newName = Console.ReadLine();
_groupConsoleUI.UpdateGroupName(groupId, newName);
}
else
{
Console.WriteLine("Неверный формат ID группы");
}
break;
case "9":
// Поиск группы
Console.Write("Введите ID группы для поиска : ");
if (int.TryParse(Console.ReadLine(), out int IdGroup))
{
_groupConsoleUI.FindGroupById(IdGroup);
}
break;
case "10":
// Генерация посещаемости на день
Console.Write("Введите номер первого занятия: ");
int firstLesson = int.Parse(Console.ReadLine());
Console.Write("Введите номер последнего занятия: ");
int lastLesson = int.Parse(Console.ReadLine());
Console.Write("Введите ID группы: ");
int groupIdForPresence = int.Parse(Console.ReadLine());
_presenceConsoleUI.GeneratePresenceForDay(DateTime.Now, groupIdForPresence, firstLesson, lastLesson);
Console.WriteLine("Посещаемость на день сгенерирована.");
break;
case "11":
// Генерация посещаемости на неделю
Console.Write("Введите номер первого занятия: ");
int firstLessonForWeek = int.Parse(Console.ReadLine());
Console.Write("Введите номер последнего занятия: ");
int lastLessonForWeek = int.Parse(Console.ReadLine());
Console.Write("Введите ID группы: ");
int groupIdForWeekPresence = int.Parse(Console.ReadLine());
_presenceConsoleUI.GeneratePresenceForWeek(DateTime.Now, groupIdForWeekPresence, firstLessonForWeek, lastLessonForWeek);
Console.WriteLine("Посещаемость на неделю сгенерирована.");
break;
case "12":
// Отображение посещаемости
Console.Write("Введите дату (гггг-мм-дд): ");
DateTime date = DateTime.Parse(Console.ReadLine());
Console.Write("Введите ID группы: ");
int groupForPresenceView = int.Parse(Console.ReadLine());
_presenceConsoleUI.DisplayPresence(date, groupForPresenceView);
break;
case "13":
// Отметить пользователя как отсутствующего
Console.Write("Введите ID пользователя: ");
userGuid = Guid.Parse(Console.ReadLine());
Console.Write("Введите номер первого занятия: ");
int firstAbsLesson = int.Parse(Console.ReadLine());
Console.Write("Введите номер последнего занятия: ");
int lastAbsLesson = int.Parse(Console.ReadLine());
Console.Write("Введите ID группы: ");
int absGroupId = int.Parse(Console.ReadLine());
_presenceConsoleUI.MarkUserAbsent(DateTime.Now, absGroupId, userGuid, firstAbsLesson, lastAbsLesson);
Console.WriteLine("Пользователь отмечен как отсутствующий.");
break;
case "14":
Console.Write("Введите ID группы: ");
int groupIdForAllPresence = int.Parse(Console.ReadLine());
_presenceConsoleUI.DisplayAllPresenceByGroup(groupIdForAllPresence);
break;
case "0":
Console.WriteLine("Выход...");
return;
default:
Console.WriteLine("Неверный выбор, попробуйте снова.");
break; break;
} }
Console.WriteLine(); Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
} }
} }
} }
} }

149
Demo/UI/PresenceConsole.cs Normal file
View File

@ -0,0 +1,149 @@
using Demo.domain.Models;
using Demo.Domain.UseCase;
using System;
using System.Collections.Generic;
namespace Demo.UI
{
public class PresenceConsole
{
private readonly UseCaseGeneratePresence _presenceUseCase;
public PresenceConsole(UseCaseGeneratePresence presenceUseCase)
{
_presenceUseCase = presenceUseCase;
}
// Метод для генерации посещаемости на день
public void GeneratePresenceForDay(DateTime date, int groupId, int firstLesson, int lastLesson)
{
try
{
_presenceUseCase.GeneratePresenceDaily(firstLesson, lastLesson, groupId, date);
Console.WriteLine("Посещаемость на день успешно сгенерирована.");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при генерации посещаемости: {ex.Message}");
}
}
// Метод для генерации посещаемости на неделю
public void GeneratePresenceForWeek(DateTime date, int groupId, int firstLesson, int lastLesson)
{
try
{
_presenceUseCase.GenerateWeeklyPresence(firstLesson, lastLesson, groupId, date);
Console.WriteLine("Посещаемость на неделю успешно сгенерирована.");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при генерации посещаемости: {ex.Message}");
}
}
// Метод для отображения посещаемости на конкретную дату и группу
public void DisplayPresence(DateTime date, int groupId)
{
try
{
List<PresenceLocalEntity> presences = _presenceUseCase.GetPresenceByDateAndGroup(groupId, date);
if (presences == null || presences.Count == 0)
{
Console.WriteLine("Нет данных о посещаемости на выбранную дату.");
return;
}
Console.WriteLine($"\n Посещаемость на {date:dd.MM.yyyy} ");
Console.WriteLine("-----------------------------------------------------");
// Сохраняем номер занятия для сравнения
int previousLessonNumber = -1;
foreach (var presence in presences)
{
// Проверяем, изменился ли номер занятия
if (previousLessonNumber != presence.LessonNumber)
{
Console.WriteLine("-----------------------------------------------------");
Console.WriteLine($" Занятие: {presence.LessonNumber} ");
Console.WriteLine("-----------------------------------------------------");
previousLessonNumber = presence.LessonNumber;
}
// Форматируем статус присутствия
string status = presence.IsAttedance ? "Присутствует" : "Отсутствует";
Console.WriteLine($"Пользователь (ID: {presence.UserGuid}) - Статус: {status}");
}
Console.WriteLine("-----------------------------------------------------");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при отображении посещаемости: {ex.Message}");
}
}
public void MarkUserAbsent(DateTime date, int groupId, Guid userGuid, int firstLesson, int lastLesson)
{
_presenceUseCase.MarkUserAbsentForLessons(userGuid, groupId, firstLesson, lastLesson, date);
}
public void DisplayAllPresenceByGroup(int groupId)
{
try
{
var presences = _presenceUseCase.GetAllPresenceByGroup(groupId);
if (presences == null || !presences.Any())
{
Console.WriteLine($"Нет данных о посещаемости для группы с ID: {groupId}.");
return;
}
// Группируем записи посещаемости по дате
var groupedPresences = presences.GroupBy(p => p.Date);
foreach (var group in groupedPresences)
{
Console.WriteLine("===================================================");
Console.WriteLine($" Дата: {group.Key:dd.MM.yyyy} ");
Console.WriteLine("===================================================");
// Сохраняем номер занятия для сравнения
int previousLessonNumber = -1;
foreach (var presence in group)
{
// Проверяем, изменился ли номер занятия
if (previousLessonNumber != presence.LessonNumber)
{
Console.WriteLine("---------------------------------------------------");
Console.WriteLine($" Занятие: {presence.LessonNumber} ");
Console.WriteLine("---------------------------------------------------");
previousLessonNumber = presence.LessonNumber;
}
// Форматируем статус присутствия
string status = presence.IsAttedance ? "✅ Присутствует" : "❌ Отсутствует";
Console.WriteLine($"Пользователь (ID: {presence.UserGuid}) - Статус: {status}");
}
Console.WriteLine("---------------------------------------------------");
}
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка при отображении посещаемости: {ex.Message}");
}
}
}
}

View File

@ -1,51 +1,74 @@
using Demo.Domain.UseCase; using Demo.Domain.UseCase;
using Demo.domain.Models;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace Demo.UI namespace Demo.UI
{ {
public class UserConsoleUI public class UserConsoleUI
{ {
UserUseCase _userUseCase; private readonly UserUseCase _userUseCase;
public UserConsoleUI(UserUseCase userUseCase) {
public UserConsoleUI(UserUseCase userUseCase)
{
_userUseCase = userUseCase; _userUseCase = userUseCase;
} }
public void RemoveUserByGuid(Guid guidUser) // Метод для отображения всех пользователей
{
string output = _userUseCase.RemoveUserByGuid(guidUser) ? "Пользователь удален" : "Пользователь не удален";
Console.WriteLine(output);
}
public void DisplayAllUsers() public void DisplayAllUsers()
{ {
Console.WriteLine("\n=== Список всех пользователей ===");
StringBuilder userOutput = new StringBuilder(); StringBuilder userOutput = new StringBuilder();
foreach (var user in _userUseCase.GetAllUsers()) foreach (var user in _userUseCase.GetAllUsers())
{ {
userOutput.AppendLine($"{user.Guid}\t{user.FIO}\t{user.Group.Name}"); userOutput.AppendLine($"{user.Guid}\t{user.FIO}\t{user.Group.Name}");
} }
Console.WriteLine(userOutput); Console.WriteLine(userOutput);
Console.WriteLine("===============================\n");
} }
public void UpdateUserGuid(Guid guidUser) // Метод для удаления пользователя по ID
public void RemoveUserById(Guid userGuid)
{ {
var user = _userUseCase.FindUserByGuid(guidUser); string output = _userUseCase.RemoveUserById(userGuid) ? "Пользователь удален" : "Пользователь не найден";
Console.WriteLine($"\n{output}\n");
}
// Метод для обновления пользователя по ID
public void UpdateUserById(Guid userGuid)
{
try
{
var user = _userUseCase.FindUserById(userGuid);
Console.WriteLine($"Текущие данные: {user.FIO}, {user.Group.Name}"); Console.WriteLine($"Текущие данные: {user.FIO}, {user.Group.Name}");
Console.Write("Введите новое ФИО: "); Console.Write("\nВведите новое ФИО: ");
string newFIO = Console.ReadLine(); string newFIO = Console.ReadLine();
user.FIO = newFIO; user.FIO = newFIO;
_userUseCase.UpdateUser(user); _userUseCase.UpdateUser(user);
Console.WriteLine("\nПользователь обновлен.\n");
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка: {ex.Message}\n");
}
} }
public void GetUserByGuid(Guid guidUser) // Метод для поиска пользователя по ID
public void FindUserById(Guid userGuid)
{ {
var user = _userUseCase.FindUserByGuid(guidUser); var user = _userUseCase.FindUserById(userGuid);
Console.WriteLine($"Пользователь найден: {user.Guid}, {user.FIO}, {user.Group.Name}"); if (user != null)
{
Console.WriteLine($"\nПользователь найден: {user.Guid}, {user.FIO}, {user.Group.Name}\n");
}
else
{
Console.WriteLine("\nПользователь не найден.\n");
}
} }
} }
} }

View File

@ -7,17 +7,813 @@
"targets": { "targets": {
".NETCoreApp,Version=v8.0": { ".NETCoreApp,Version=v8.0": {
"Demo/1.0.0": { "Demo/1.0.0": {
"dependencies": {
"Microsoft.EntityFrameworkCore": "8.0.10",
"Microsoft.EntityFrameworkCore.Design": "8.0.10",
"Microsoft.Extensions.DependencyInjection": "8.0.1",
"Npgsql.EntityFrameworkCore.PostgreSQL": "8.0.10"
},
"runtime": { "runtime": {
"Demo.dll": {} "Demo.dll": {}
} }
},
"Humanizer.Core/2.14.1": {
"runtime": {
"lib/net6.0/Humanizer.dll": {
"assemblyVersion": "2.14.0.0",
"fileVersion": "2.14.1.48190"
} }
} }
}, },
"Microsoft.Bcl.AsyncInterfaces/6.0.0": {
"runtime": {
"lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"Microsoft.CodeAnalysis.Analyzers/3.3.3": {},
"Microsoft.CodeAnalysis.Common/4.5.0": {
"dependencies": {
"Microsoft.CodeAnalysis.Analyzers": "3.3.3",
"System.Collections.Immutable": "6.0.0",
"System.Reflection.Metadata": "6.0.1",
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
"System.Text.Encoding.CodePages": "6.0.0"
},
"runtime": {
"lib/netcoreapp3.1/Microsoft.CodeAnalysis.dll": {
"assemblyVersion": "4.5.0.0",
"fileVersion": "4.500.23.10905"
}
},
"resources": {
"lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.resources.dll": {
"locale": "cs"
},
"lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.resources.dll": {
"locale": "de"
},
"lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.resources.dll": {
"locale": "es"
},
"lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.resources.dll": {
"locale": "fr"
},
"lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.resources.dll": {
"locale": "it"
},
"lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.resources.dll": {
"locale": "ja"
},
"lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.resources.dll": {
"locale": "ko"
},
"lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.resources.dll": {
"locale": "pl"
},
"lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.resources.dll": {
"locale": "pt-BR"
},
"lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.resources.dll": {
"locale": "ru"
},
"lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.resources.dll": {
"locale": "tr"
},
"lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.resources.dll": {
"locale": "zh-Hans"
},
"lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.resources.dll": {
"locale": "zh-Hant"
}
}
},
"Microsoft.CodeAnalysis.CSharp/4.5.0": {
"dependencies": {
"Microsoft.CodeAnalysis.Common": "4.5.0"
},
"runtime": {
"lib/netcoreapp3.1/Microsoft.CodeAnalysis.CSharp.dll": {
"assemblyVersion": "4.5.0.0",
"fileVersion": "4.500.23.10905"
}
},
"resources": {
"lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "cs"
},
"lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "de"
},
"lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "es"
},
"lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "fr"
},
"lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "it"
},
"lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "ja"
},
"lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "ko"
},
"lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "pl"
},
"lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "pt-BR"
},
"lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "ru"
},
"lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "tr"
},
"lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "zh-Hans"
},
"lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.dll": {
"locale": "zh-Hant"
}
}
},
"Microsoft.CodeAnalysis.CSharp.Workspaces/4.5.0": {
"dependencies": {
"Humanizer.Core": "2.14.1",
"Microsoft.CodeAnalysis.CSharp": "4.5.0",
"Microsoft.CodeAnalysis.Common": "4.5.0",
"Microsoft.CodeAnalysis.Workspaces.Common": "4.5.0"
},
"runtime": {
"lib/netcoreapp3.1/Microsoft.CodeAnalysis.CSharp.Workspaces.dll": {
"assemblyVersion": "4.5.0.0",
"fileVersion": "4.500.23.10905"
}
},
"resources": {
"lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "cs"
},
"lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "de"
},
"lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "es"
},
"lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "fr"
},
"lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "it"
},
"lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "ja"
},
"lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "ko"
},
"lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "pl"
},
"lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "pt-BR"
},
"lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "ru"
},
"lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "tr"
},
"lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "zh-Hans"
},
"lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.CSharp.Workspaces.resources.dll": {
"locale": "zh-Hant"
}
}
},
"Microsoft.CodeAnalysis.Workspaces.Common/4.5.0": {
"dependencies": {
"Humanizer.Core": "2.14.1",
"Microsoft.Bcl.AsyncInterfaces": "6.0.0",
"Microsoft.CodeAnalysis.Common": "4.5.0",
"System.Composition": "6.0.0",
"System.IO.Pipelines": "6.0.3",
"System.Threading.Channels": "6.0.0"
},
"runtime": {
"lib/netcoreapp3.1/Microsoft.CodeAnalysis.Workspaces.dll": {
"assemblyVersion": "4.5.0.0",
"fileVersion": "4.500.23.10905"
}
},
"resources": {
"lib/netcoreapp3.1/cs/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "cs"
},
"lib/netcoreapp3.1/de/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "de"
},
"lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "es"
},
"lib/netcoreapp3.1/fr/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "fr"
},
"lib/netcoreapp3.1/it/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "it"
},
"lib/netcoreapp3.1/ja/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "ja"
},
"lib/netcoreapp3.1/ko/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "ko"
},
"lib/netcoreapp3.1/pl/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "pl"
},
"lib/netcoreapp3.1/pt-BR/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "pt-BR"
},
"lib/netcoreapp3.1/ru/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "ru"
},
"lib/netcoreapp3.1/tr/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "tr"
},
"lib/netcoreapp3.1/zh-Hans/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "zh-Hans"
},
"lib/netcoreapp3.1/zh-Hant/Microsoft.CodeAnalysis.Workspaces.resources.dll": {
"locale": "zh-Hant"
}
}
},
"Microsoft.EntityFrameworkCore/8.0.10": {
"dependencies": {
"Microsoft.EntityFrameworkCore.Abstractions": "8.0.10",
"Microsoft.EntityFrameworkCore.Analyzers": "8.0.10",
"Microsoft.Extensions.Caching.Memory": "8.0.1",
"Microsoft.Extensions.Logging": "8.0.1"
},
"runtime": {
"lib/net8.0/Microsoft.EntityFrameworkCore.dll": {
"assemblyVersion": "8.0.10.0",
"fileVersion": "8.0.1024.46708"
}
}
},
"Microsoft.EntityFrameworkCore.Abstractions/8.0.10": {
"runtime": {
"lib/net8.0/Microsoft.EntityFrameworkCore.Abstractions.dll": {
"assemblyVersion": "8.0.10.0",
"fileVersion": "8.0.1024.46708"
}
}
},
"Microsoft.EntityFrameworkCore.Analyzers/8.0.10": {},
"Microsoft.EntityFrameworkCore.Design/8.0.10": {
"dependencies": {
"Humanizer.Core": "2.14.1",
"Microsoft.CodeAnalysis.CSharp.Workspaces": "4.5.0",
"Microsoft.EntityFrameworkCore.Relational": "8.0.10",
"Microsoft.Extensions.DependencyModel": "8.0.2",
"Mono.TextTemplating": "2.2.1"
},
"runtime": {
"lib/net8.0/Microsoft.EntityFrameworkCore.Design.dll": {
"assemblyVersion": "8.0.10.0",
"fileVersion": "8.0.1024.46708"
}
}
},
"Microsoft.EntityFrameworkCore.Relational/8.0.10": {
"dependencies": {
"Microsoft.EntityFrameworkCore": "8.0.10",
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
},
"runtime": {
"lib/net8.0/Microsoft.EntityFrameworkCore.Relational.dll": {
"assemblyVersion": "8.0.10.0",
"fileVersion": "8.0.1024.46708"
}
}
},
"Microsoft.Extensions.Caching.Abstractions/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
},
"runtime": {
"lib/net8.0/Microsoft.Extensions.Caching.Abstractions.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.23.53103"
}
}
},
"Microsoft.Extensions.Caching.Memory/8.0.1": {
"dependencies": {
"Microsoft.Extensions.Caching.Abstractions": "8.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
"Microsoft.Extensions.Options": "8.0.2",
"Microsoft.Extensions.Primitives": "8.0.0"
},
"runtime": {
"lib/net8.0/Microsoft.Extensions.Caching.Memory.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.1024.46610"
}
}
},
"Microsoft.Extensions.Configuration.Abstractions/8.0.0": {
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
},
"runtime": {
"lib/net8.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.23.53103"
}
}
},
"Microsoft.Extensions.DependencyInjection/8.0.1": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2"
},
"runtime": {
"lib/net8.0/Microsoft.Extensions.DependencyInjection.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.1024.46610"
}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.2": {
"runtime": {
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.1024.46610"
}
}
},
"Microsoft.Extensions.DependencyModel/8.0.2": {
"runtime": {
"lib/net8.0/Microsoft.Extensions.DependencyModel.dll": {
"assemblyVersion": "8.0.0.2",
"fileVersion": "8.0.1024.46610"
}
}
},
"Microsoft.Extensions.Logging/8.0.1": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "8.0.1",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
"Microsoft.Extensions.Options": "8.0.2"
},
"runtime": {
"lib/net8.0/Microsoft.Extensions.Logging.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.1024.46610"
}
}
},
"Microsoft.Extensions.Logging.Abstractions/8.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2"
},
"runtime": {
"lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.1024.46610"
}
}
},
"Microsoft.Extensions.Options/8.0.2": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Primitives": "8.0.0"
},
"runtime": {
"lib/net8.0/Microsoft.Extensions.Options.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.224.6711"
}
}
},
"Microsoft.Extensions.Primitives/8.0.0": {
"runtime": {
"lib/net8.0/Microsoft.Extensions.Primitives.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.23.53103"
}
}
},
"Mono.TextTemplating/2.2.1": {
"dependencies": {
"System.CodeDom": "4.4.0"
},
"runtime": {
"lib/netstandard2.0/Mono.TextTemplating.dll": {
"assemblyVersion": "2.2.0.0",
"fileVersion": "2.2.1.1"
}
}
},
"Npgsql/8.0.5": {
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "8.0.2"
},
"runtime": {
"lib/net8.0/Npgsql.dll": {
"assemblyVersion": "8.0.5.0",
"fileVersion": "8.0.5.0"
}
}
},
"Npgsql.EntityFrameworkCore.PostgreSQL/8.0.10": {
"dependencies": {
"Microsoft.EntityFrameworkCore": "8.0.10",
"Microsoft.EntityFrameworkCore.Abstractions": "8.0.10",
"Microsoft.EntityFrameworkCore.Relational": "8.0.10",
"Npgsql": "8.0.5"
},
"runtime": {
"lib/net8.0/Npgsql.EntityFrameworkCore.PostgreSQL.dll": {
"assemblyVersion": "8.0.10.0",
"fileVersion": "8.0.10.0"
}
}
},
"System.CodeDom/4.4.0": {
"runtime": {
"lib/netstandard2.0/System.CodeDom.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.25519.3"
}
}
},
"System.Collections.Immutable/6.0.0": {
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Composition/6.0.0": {
"dependencies": {
"System.Composition.AttributedModel": "6.0.0",
"System.Composition.Convention": "6.0.0",
"System.Composition.Hosting": "6.0.0",
"System.Composition.Runtime": "6.0.0",
"System.Composition.TypedParts": "6.0.0"
}
},
"System.Composition.AttributedModel/6.0.0": {
"runtime": {
"lib/net6.0/System.Composition.AttributedModel.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"System.Composition.Convention/6.0.0": {
"dependencies": {
"System.Composition.AttributedModel": "6.0.0"
},
"runtime": {
"lib/net6.0/System.Composition.Convention.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"System.Composition.Hosting/6.0.0": {
"dependencies": {
"System.Composition.Runtime": "6.0.0"
},
"runtime": {
"lib/net6.0/System.Composition.Hosting.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"System.Composition.Runtime/6.0.0": {
"runtime": {
"lib/net6.0/System.Composition.Runtime.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"System.Composition.TypedParts/6.0.0": {
"dependencies": {
"System.Composition.AttributedModel": "6.0.0",
"System.Composition.Hosting": "6.0.0",
"System.Composition.Runtime": "6.0.0"
},
"runtime": {
"lib/net6.0/System.Composition.TypedParts.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.21.52210"
}
}
},
"System.IO.Pipelines/6.0.3": {
"runtime": {
"lib/net6.0/System.IO.Pipelines.dll": {
"assemblyVersion": "6.0.0.0",
"fileVersion": "6.0.522.21309"
}
}
},
"System.Reflection.Metadata/6.0.1": {
"dependencies": {
"System.Collections.Immutable": "6.0.0"
}
},
"System.Runtime.CompilerServices.Unsafe/6.0.0": {},
"System.Text.Encoding.CodePages/6.0.0": {
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Threading.Channels/6.0.0": {}
}
},
"libraries": { "libraries": {
"Demo/1.0.0": { "Demo/1.0.0": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
},
"Humanizer.Core/2.14.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw==",
"path": "humanizer.core/2.14.1",
"hashPath": "humanizer.core.2.14.1.nupkg.sha512"
},
"Microsoft.Bcl.AsyncInterfaces/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg==",
"path": "microsoft.bcl.asyncinterfaces/6.0.0",
"hashPath": "microsoft.bcl.asyncinterfaces.6.0.0.nupkg.sha512"
},
"Microsoft.CodeAnalysis.Analyzers/3.3.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-j/rOZtLMVJjrfLRlAMckJLPW/1rze9MT1yfWqSIbUPGRu1m1P0fuo9PmqapwsmePfGB5PJrudQLvmUOAMF0DqQ==",
"path": "microsoft.codeanalysis.analyzers/3.3.3",
"hashPath": "microsoft.codeanalysis.analyzers.3.3.3.nupkg.sha512"
},
"Microsoft.CodeAnalysis.Common/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-lwAbIZNdnY0SUNoDmZHkVUwLO8UyNnyyh1t/4XsbFxi4Ounb3xszIYZaWhyj5ZjyfcwqwmtMbE7fUTVCqQEIdQ==",
"path": "microsoft.codeanalysis.common/4.5.0",
"hashPath": "microsoft.codeanalysis.common.4.5.0.nupkg.sha512"
},
"Microsoft.CodeAnalysis.CSharp/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-cM59oMKAOxvdv76bdmaKPy5hfj+oR+zxikWoueEB7CwTko7mt9sVKZI8Qxlov0C/LuKEG+WQwifepqL3vuTiBQ==",
"path": "microsoft.codeanalysis.csharp/4.5.0",
"hashPath": "microsoft.codeanalysis.csharp.4.5.0.nupkg.sha512"
},
"Microsoft.CodeAnalysis.CSharp.Workspaces/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-h74wTpmGOp4yS4hj+EvNzEiPgg/KVs2wmSfTZ81upJZOtPkJsVkgfsgtxxqmAeapjT/vLKfmYV0bS8n5MNVP+g==",
"path": "microsoft.codeanalysis.csharp.workspaces/4.5.0",
"hashPath": "microsoft.codeanalysis.csharp.workspaces.4.5.0.nupkg.sha512"
},
"Microsoft.CodeAnalysis.Workspaces.Common/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-l4dDRmGELXG72XZaonnOeORyD/T5RpEu5LGHOUIhnv+MmUWDY/m1kWXGwtcgQ5CJ5ynkFiRnIYzTKXYjUs7rbw==",
"path": "microsoft.codeanalysis.workspaces.common/4.5.0",
"hashPath": "microsoft.codeanalysis.workspaces.common.4.5.0.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore/8.0.10": {
"type": "package",
"serviceable": true,
"sha512": "sha512-PPkQdIqfR1nU3n6YgGGDk8G+eaYbaAKM1AzIQtlPNTKf10Osg3N9T+iK9AlnSA/ujsK00flPpFHVfJrbuBFS1A==",
"path": "microsoft.entityframeworkcore/8.0.10",
"hashPath": "microsoft.entityframeworkcore.8.0.10.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Abstractions/8.0.10": {
"type": "package",
"serviceable": true,
"sha512": "sha512-FV0QlcX9INY4kAD2o72uPtyOh0nZut2jB11Jf9mNYBtHay8gDLe+x4AbXFwuQg+eSvofjT7naV82e827zGfyMg==",
"path": "microsoft.entityframeworkcore.abstractions/8.0.10",
"hashPath": "microsoft.entityframeworkcore.abstractions.8.0.10.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Analyzers/8.0.10": {
"type": "package",
"serviceable": true,
"sha512": "sha512-51KkPIc0EMv/gVXhPIUi6cwJE9Mvh+PLr4Lap4naLcsoGZ0lF2SvOPgUUprwRV3MnN7nyD1XPhT5RJ/p+xFAXw==",
"path": "microsoft.entityframeworkcore.analyzers/8.0.10",
"hashPath": "microsoft.entityframeworkcore.analyzers.8.0.10.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Design/8.0.10": {
"type": "package",
"serviceable": true,
"sha512": "sha512-uGNjfKvAsql2KHRqxlK5wHo8mMC60G/FecrFKEjJgeIxtUAbSXGOgKGw/gD9flO5Fzzt1C7uxfIcr6ZsMmFkeg==",
"path": "microsoft.entityframeworkcore.design/8.0.10",
"hashPath": "microsoft.entityframeworkcore.design.8.0.10.nupkg.sha512"
},
"Microsoft.EntityFrameworkCore.Relational/8.0.10": {
"type": "package",
"serviceable": true,
"sha512": "sha512-OefBEE47kGKPRPV3OT+FAW6o5BFgLk2D9EoeWVy7NbOepzUneayLQxbVE098FfedTyMwxvZQoDD9LrvZc3MadA==",
"path": "microsoft.entityframeworkcore.relational/8.0.10",
"hashPath": "microsoft.entityframeworkcore.relational.8.0.10.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Abstractions/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3KuSxeHoNYdxVYfg2IRZCThcrlJ1XJqIXkAWikCsbm5C/bCjv7G0WoKDyuR98Q+T607QT2Zl5GsbGRkENcV2yQ==",
"path": "microsoft.extensions.caching.abstractions/8.0.0",
"hashPath": "microsoft.extensions.caching.abstractions.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Memory/8.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-HFDnhYLccngrzyGgHkjEDU5FMLn4MpOsr5ElgsBMC4yx6lJh4jeWO7fHS8+TXPq+dgxCmUa/Trl8svObmwW4QA==",
"path": "microsoft.extensions.caching.memory/8.0.1",
"hashPath": "microsoft.extensions.caching.memory.8.0.1.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Abstractions/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==",
"path": "microsoft.extensions.configuration.abstractions/8.0.0",
"hashPath": "microsoft.extensions.configuration.abstractions.8.0.0.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection/8.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-BmANAnR5Xd4Oqw7yQ75xOAYODybZQRzdeNucg7kS5wWKd2PNnMdYtJ2Vciy0QLylRmv42DGl5+AFL9izA6F1Rw==",
"path": "microsoft.extensions.dependencyinjection/8.0.1",
"hashPath": "microsoft.extensions.dependencyinjection.8.0.1.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3iE7UF7MQkCv1cxzCahz+Y/guQbTqieyxyaWKhrRO91itI9cOKO76OHeQDahqG4MmW5umr3CcCvGmK92lWNlbg==",
"path": "microsoft.extensions.dependencyinjection.abstractions/8.0.2",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.8.0.2.nupkg.sha512"
},
"Microsoft.Extensions.DependencyModel/8.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-mUBDZZRgZrSyFOsJ2qJJ9fXfqd/kXJwf3AiDoqLD9m6TjY5OO/vLNOb9fb4juC0487eq4hcGN/M2Rh/CKS7QYw==",
"path": "microsoft.extensions.dependencymodel/8.0.2",
"hashPath": "microsoft.extensions.dependencymodel.8.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Logging/8.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-4x+pzsQEbqxhNf1QYRr5TDkLP9UsLT3A6MdRKDDEgrW7h1ljiEPgTNhKYUhNCCAaVpQECVQ+onA91PTPnIp6Lw==",
"path": "microsoft.extensions.logging/8.0.1",
"hashPath": "microsoft.extensions.logging.8.0.1.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Abstractions/8.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-nroMDjS7hNBPtkZqVBbSiQaQjWRDxITI8Y7XnDs97rqG3EbzVTNLZQf7bIeUJcaHOV8bca47s1Uxq94+2oGdxA==",
"path": "microsoft.extensions.logging.abstractions/8.0.2",
"hashPath": "microsoft.extensions.logging.abstractions.8.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Options/8.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dWGKvhFybsaZpGmzkGCbNNwBD1rVlWzrZKANLW/CcbFJpCEceMCGzT7zZwHOGBCbwM0SzBuceMj5HN1LKV1QqA==",
"path": "microsoft.extensions.options/8.0.2",
"hashPath": "microsoft.extensions.options.8.0.2.nupkg.sha512"
},
"Microsoft.Extensions.Primitives/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g==",
"path": "microsoft.extensions.primitives/8.0.0",
"hashPath": "microsoft.extensions.primitives.8.0.0.nupkg.sha512"
},
"Mono.TextTemplating/2.2.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-KZYeKBET/2Z0gY1WlTAK7+RHTl7GSbtvTLDXEZZojUdAPqpQNDL6tHv7VUpqfX5VEOh+uRGKaZXkuD253nEOBQ==",
"path": "mono.texttemplating/2.2.1",
"hashPath": "mono.texttemplating.2.2.1.nupkg.sha512"
},
"Npgsql/8.0.5": {
"type": "package",
"serviceable": true,
"sha512": "sha512-zRG5V8cyeZLpzJlKzFKjEwkRMYIYnHWJvEor2lWXeccS2E1G2nIWYYhnukB51iz5XsWSVEtqg3AxTWM0QJ6vfg==",
"path": "npgsql/8.0.5",
"hashPath": "npgsql.8.0.5.nupkg.sha512"
},
"Npgsql.EntityFrameworkCore.PostgreSQL/8.0.10": {
"type": "package",
"serviceable": true,
"sha512": "sha512-gFPl9Dmxih7Yi4tZ3bITzZFzbxFMBx04gqTqcjoL2r5VEW+O2TA5UVw/wm/XW26NAJ7sg59Je0+9QrwiZt6MPQ==",
"path": "npgsql.entityframeworkcore.postgresql/8.0.10",
"hashPath": "npgsql.entityframeworkcore.postgresql.8.0.10.nupkg.sha512"
},
"System.CodeDom/4.4.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-2sCCb7doXEwtYAbqzbF/8UAeDRMNmPaQbU2q50Psg1J9KzumyVVCgKQY8s53WIPTufNT0DpSe9QRvVjOzfDWBA==",
"path": "system.codedom/4.4.0",
"hashPath": "system.codedom.4.4.0.nupkg.sha512"
},
"System.Collections.Immutable/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==",
"path": "system.collections.immutable/6.0.0",
"hashPath": "system.collections.immutable.6.0.0.nupkg.sha512"
},
"System.Composition/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-d7wMuKQtfsxUa7S13tITC8n1cQzewuhD5iDjZtK2prwFfKVzdYtgrTHgjaV03Zq7feGQ5gkP85tJJntXwInsJA==",
"path": "system.composition/6.0.0",
"hashPath": "system.composition.6.0.0.nupkg.sha512"
},
"System.Composition.AttributedModel/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-WK1nSDLByK/4VoC7fkNiFuTVEiperuCN/Hyn+VN30R+W2ijO1d0Z2Qm0ScEl9xkSn1G2MyapJi8xpf4R8WRa/w==",
"path": "system.composition.attributedmodel/6.0.0",
"hashPath": "system.composition.attributedmodel.6.0.0.nupkg.sha512"
},
"System.Composition.Convention/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-XYi4lPRdu5bM4JVJ3/UIHAiG6V6lWWUlkhB9ab4IOq0FrRsp0F4wTyV4Dj+Ds+efoXJ3qbLqlvaUozDO7OLeXA==",
"path": "system.composition.convention/6.0.0",
"hashPath": "system.composition.convention.6.0.0.nupkg.sha512"
},
"System.Composition.Hosting/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-w/wXjj7kvxuHPLdzZ0PAUt++qJl03t7lENmb2Oev0n3zbxyNULbWBlnd5J5WUMMv15kg5o+/TCZFb6lSwfaUUQ==",
"path": "system.composition.hosting/6.0.0",
"hashPath": "system.composition.hosting.6.0.0.nupkg.sha512"
},
"System.Composition.Runtime/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-qkRH/YBaMPTnzxrS5RDk1juvqed4A6HOD/CwRcDGyPpYps1J27waBddiiq1y93jk2ZZ9wuA/kynM+NO0kb3PKg==",
"path": "system.composition.runtime/6.0.0",
"hashPath": "system.composition.runtime.6.0.0.nupkg.sha512"
},
"System.Composition.TypedParts/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-iUR1eHrL8Cwd82neQCJ00MpwNIBs4NZgXzrPqx8NJf/k4+mwBO0XCRmHYJT4OLSwDDqh5nBLJWkz5cROnrGhRA==",
"path": "system.composition.typedparts/6.0.0",
"hashPath": "system.composition.typedparts.6.0.0.nupkg.sha512"
},
"System.IO.Pipelines/6.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ryTgF+iFkpGZY1vRQhfCzX0xTdlV3pyaTTqRu2ETbEv+HlV7O6y7hyQURnghNIXvctl5DuZ//Dpks6HdL/Txgw==",
"path": "system.io.pipelines/6.0.3",
"hashPath": "system.io.pipelines.6.0.3.nupkg.sha512"
},
"System.Reflection.Metadata/6.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-III/lNMSn0ZRBuM9m5Cgbiho5j81u0FAEagFX5ta2DKbljZ3T0IpD8j+BIiHQPeKqJppWS9bGEp6JnKnWKze0g==",
"path": "system.reflection.metadata/6.0.1",
"hashPath": "system.reflection.metadata.6.0.1.nupkg.sha512"
},
"System.Runtime.CompilerServices.Unsafe/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
"path": "system.runtime.compilerservices.unsafe/6.0.0",
"hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512"
},
"System.Text.Encoding.CodePages/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
"path": "system.text.encoding.codepages/6.0.0",
"hashPath": "system.text.encoding.codepages.6.0.0.nupkg.sha512"
},
"System.Threading.Channels/6.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-TY8/9+tI0mNaUMgntOxxaq2ndTkdXqLSxvPmas7XEqOlv9lQtB7wLjYGd756lOaO7Dvb5r/WXhluM+0Xe87v5Q==",
"path": "system.threading.channels/6.0.0",
"hashPath": "system.threading.channels.6.0.0.nupkg.sha512"
} }
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -6,6 +6,7 @@
"version": "8.0.0" "version": "8.0.0"
}, },
"configProperties": { "configProperties": {
"System.Reflection.NullabilityInfoContext.IsSupported": true,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More