1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-21 12:05:42 +01:00

Make AC Repos Nullable (#4610)

This commit is contained in:
Justin Baur 2024-08-15 20:47:21 -04:00 committed by GitHub
parent aa34bbb0e6
commit c37f4b45a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 74 additions and 52 deletions

View File

@ -2,11 +2,13 @@
using Bit.Core.Models.Data;
using Bit.Core.Repositories;
#nullable enable
namespace Bit.Core.AdminConsole.Repositories;
public interface IGroupRepository : IRepository<Group, Guid>
{
Task<Tuple<Group, ICollection<CollectionAccessSelection>>> GetByIdWithCollectionsAsync(Guid id);
Task<Tuple<Group?, ICollection<CollectionAccessSelection>>> GetByIdWithCollectionsAsync(Guid id);
Task<ICollection<Group>> GetManyByOrganizationIdAsync(Guid organizationId);
Task<ICollection<Tuple<Group, ICollection<CollectionAccessSelection>>>> GetManyWithCollectionsByOrganizationIdAsync(
Guid organizationId);

View File

@ -1,18 +1,20 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Models.Data.Organizations;
#nullable enable
namespace Bit.Core.Repositories;
public interface IOrganizationRepository : IRepository<Organization, Guid>
{
Task<Organization> GetByIdentifierAsync(string identifier);
Task<Organization?> GetByIdentifierAsync(string identifier);
Task<ICollection<Organization>> GetManyByEnabledAsync();
Task<ICollection<Organization>> GetManyByUserIdAsync(Guid userId);
Task<ICollection<Organization>> SearchAsync(string name, string userEmail, bool? paid, int skip, int take);
Task UpdateStorageAsync(Guid id);
Task<ICollection<OrganizationAbility>> GetManyAbilitiesAsync();
Task<Organization> GetByLicenseKeyAsync(string licenseKey);
Task<SelfHostedOrganizationDetails> GetSelfHostedOrganizationDetailsById(Guid id);
Task<Organization?> GetByLicenseKeyAsync(string licenseKey);
Task<SelfHostedOrganizationDetails?> GetSelfHostedOrganizationDetailsById(Guid id);
Task<ICollection<Organization>> SearchUnassignedToProviderAsync(string name, string ownerEmail, int skip, int take);
Task<IEnumerable<string>> GetOwnerEmailAddressesById(Guid organizationId);
}

View File

@ -5,6 +5,8 @@ using Bit.Core.Enums;
using Bit.Core.Models.Data;
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
#nullable enable
namespace Bit.Core.Repositories;
public interface IOrganizationUserRepository : IRepository<OrganizationUser, Guid>
@ -17,26 +19,26 @@ public interface IOrganizationUserRepository : IRepository<OrganizationUser, Gui
Task<int> GetCountByOrganizationAsync(Guid organizationId, string email, bool onlyRegisteredUsers);
Task<int> GetOccupiedSeatCountByOrganizationIdAsync(Guid organizationId);
Task<ICollection<string>> SelectKnownEmailsAsync(Guid organizationId, IEnumerable<string> emails, bool onlyRegisteredUsers);
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, Guid userId);
Task<Tuple<OrganizationUser, ICollection<CollectionAccessSelection>>> GetByIdWithCollectionsAsync(Guid id);
Task<OrganizationUserUserDetails> GetDetailsByIdAsync(Guid id);
Task<Tuple<OrganizationUserUserDetails, ICollection<CollectionAccessSelection>>>
Task<OrganizationUser?> GetByOrganizationAsync(Guid organizationId, Guid userId);
Task<Tuple<OrganizationUser?, ICollection<CollectionAccessSelection>>> GetByIdWithCollectionsAsync(Guid id);
Task<OrganizationUserUserDetails?> GetDetailsByIdAsync(Guid id);
Task<Tuple<OrganizationUserUserDetails?, ICollection<CollectionAccessSelection>>>
GetDetailsByIdWithCollectionsAsync(Guid id);
Task<ICollection<OrganizationUserUserDetails>> GetManyDetailsByOrganizationAsync(Guid organizationId, bool includeGroups = false, bool includeCollections = false);
Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetailsByUserAsync(Guid userId,
OrganizationUserStatusType? status = null);
Task<OrganizationUserOrganizationDetails> GetDetailsByUserAsync(Guid userId, Guid organizationId,
Task<OrganizationUserOrganizationDetails?> GetDetailsByUserAsync(Guid userId, Guid organizationId,
OrganizationUserStatusType? status = null);
Task UpdateGroupsAsync(Guid orgUserId, IEnumerable<Guid> groupIds);
Task UpsertManyAsync(IEnumerable<OrganizationUser> organizationUsers);
Task<Guid> CreateAsync(OrganizationUser obj, IEnumerable<CollectionAccessSelection> collections);
Task<ICollection<Guid>> CreateManyAsync(IEnumerable<OrganizationUser> organizationIdUsers);
Task<ICollection<Guid>?> CreateManyAsync(IEnumerable<OrganizationUser> organizationIdUsers);
Task ReplaceAsync(OrganizationUser obj, IEnumerable<CollectionAccessSelection> collections);
Task ReplaceManyAsync(IEnumerable<OrganizationUser> organizationUsers);
Task<ICollection<OrganizationUser>> GetManyByManyUsersAsync(IEnumerable<Guid> userIds);
Task<ICollection<OrganizationUser>> GetManyAsync(IEnumerable<Guid> Ids);
Task DeleteManyAsync(IEnumerable<Guid> userIds);
Task<OrganizationUser> GetByOrganizationEmailAsync(Guid organizationId, string email);
Task<OrganizationUser?> GetByOrganizationEmailAsync(Guid organizationId, string email);
Task<IEnumerable<OrganizationUserPublicKey>> GetManyPublicKeysByOrganizationUserAsync(Guid organizationId, IEnumerable<Guid> Ids);
Task<IEnumerable<OrganizationUserUserDetails>> GetManyByMinimumRoleAsync(Guid organizationId, OrganizationUserType minRole);
Task RevokeAsync(Guid id);

View File

@ -2,11 +2,13 @@
using Bit.Core.AdminConsole.Enums;
using Bit.Core.Repositories;
#nullable enable
namespace Bit.Core.AdminConsole.Repositories;
public interface IPolicyRepository : IRepository<Policy, Guid>
{
Task<Policy> GetByOrganizationIdTypeAsync(Guid organizationId, PolicyType type);
Task<Policy?> GetByOrganizationIdTypeAsync(Guid organizationId, PolicyType type);
Task<ICollection<Policy>> GetManyByOrganizationIdAsync(Guid organizationId);
Task<ICollection<Policy>> GetManyByUserIdAsync(Guid userId);
}

View File

@ -2,13 +2,15 @@
using Bit.Core.AdminConsole.Models.Data.Provider;
using Bit.Core.Repositories;
#nullable enable
namespace Bit.Core.AdminConsole.Repositories;
public interface IProviderOrganizationRepository : IRepository<ProviderOrganization, Guid>
{
Task<ICollection<ProviderOrganization>> CreateManyAsync(IEnumerable<ProviderOrganization> providerOrganizations);
Task<ICollection<ProviderOrganization>?> CreateManyAsync(IEnumerable<ProviderOrganization> providerOrganizations);
Task<ICollection<ProviderOrganizationOrganizationDetails>> GetManyDetailsByProviderAsync(Guid providerId);
Task<ProviderOrganization> GetByOrganizationId(Guid organizationId);
Task<ProviderOrganization?> GetByOrganizationId(Guid organizationId);
Task<IEnumerable<ProviderOrganizationProviderDetails>> GetManyByUserAsync(Guid userId);
Task<int> GetCountByOrganizationIdsAsync(IEnumerable<Guid> organizationIds);
}

View File

@ -2,11 +2,13 @@
using Bit.Core.AdminConsole.Models.Data.Provider;
using Bit.Core.Repositories;
#nullable enable
namespace Bit.Core.AdminConsole.Repositories;
public interface IProviderRepository : IRepository<Provider, Guid>
{
Task<Provider> GetByOrganizationIdAsync(Guid organizationId);
Task<Provider?> GetByOrganizationIdAsync(Guid organizationId);
Task<ICollection<Provider>> SearchAsync(string name, string userEmail, int skip, int take);
Task<ICollection<ProviderAbility>> GetManyAbilitiesAsync();
}

View File

@ -3,6 +3,8 @@ using Bit.Core.AdminConsole.Enums.Provider;
using Bit.Core.AdminConsole.Models.Data.Provider;
using Bit.Core.Repositories;
#nullable enable
namespace Bit.Core.AdminConsole.Repositories;
public interface IProviderUserRepository : IRepository<ProviderUser, Guid>
@ -10,7 +12,7 @@ public interface IProviderUserRepository : IRepository<ProviderUser, Guid>
Task<int> GetCountByProviderAsync(Guid providerId, string email, bool onlyRegisteredUsers);
Task<ICollection<ProviderUser>> GetManyAsync(IEnumerable<Guid> ids);
Task<ICollection<ProviderUser>> GetManyByUserAsync(Guid userId);
Task<ProviderUser> GetByProviderUserAsync(Guid providerId, Guid userId);
Task<ProviderUser?> GetByProviderUserAsync(Guid providerId, Guid userId);
Task<ICollection<ProviderUser>> GetManyByProviderAsync(Guid providerId, ProviderUserType? type = null);
Task<ICollection<ProviderUserUserDetails>> GetManyDetailsByProviderAsync(Guid providerId, ProviderUserStatusType? status = null);
Task<ICollection<ProviderUserProviderDetails>> GetManyDetailsByUserAsync(Guid userId,

View File

@ -2,6 +2,8 @@
using Bit.Core.Entities;
using Dapper;
#nullable enable
namespace Bit.Infrastructure.Dapper.AdminConsole.Helpers;
public static class OrganizationUserHelpers
@ -11,7 +13,7 @@ public static class OrganizationUserHelpers
var table = new DataTable();
table.SetTypeName("[dbo].[OrganizationUserType2]");
var columnData = new List<(string name, Type type, Func<OrganizationUser, object> getter)>
var columnData = new List<(string name, Type type, Func<OrganizationUser, object?> getter)>
{
(nameof(OrganizationUser.Id), typeof(Guid), ou => ou.Id),
(nameof(OrganizationUser.OrganizationId), typeof(Guid), ou => ou.OrganizationId),

View File

@ -10,6 +10,8 @@ using Bit.Infrastructure.Dapper.Repositories;
using Dapper;
using Microsoft.Data.SqlClient;
#nullable enable
namespace Bit.Infrastructure.Dapper.AdminConsole.Repositories;
public class GroupRepository : Repository<Group, Guid>, IGroupRepository
@ -22,7 +24,7 @@ public class GroupRepository : Repository<Group, Guid>, IGroupRepository
: base(connectionString, readOnlyConnectionString)
{ }
public async Task<Tuple<Group, ICollection<CollectionAccessSelection>>> GetByIdWithCollectionsAsync(Guid id)
public async Task<Tuple<Group?, ICollection<CollectionAccessSelection>>> GetByIdWithCollectionsAsync(Guid id)
{
using (var connection = new SqlConnection(ConnectionString))
{
@ -34,7 +36,7 @@ public class GroupRepository : Repository<Group, Guid>, IGroupRepository
var group = await results.ReadFirstOrDefaultAsync<Group>();
var colletions = (await results.ReadAsync<CollectionAccessSelection>()).ToList();
return new Tuple<Group, ICollection<CollectionAccessSelection>>(group, colletions);
return new Tuple<Group?, ICollection<CollectionAccessSelection>>(group, colletions);
}
}
@ -136,7 +138,7 @@ public class GroupRepository : Repository<Group, Guid>, IGroupRepository
public async Task CreateAsync(Group obj, IEnumerable<CollectionAccessSelection> collections)
{
obj.SetNewId();
var objWithCollections = JsonSerializer.Deserialize<GroupWithCollections>(JsonSerializer.Serialize(obj));
var objWithCollections = JsonSerializer.Deserialize<GroupWithCollections>(JsonSerializer.Serialize(obj))!;
objWithCollections.Collections = collections.ToArrayTVP();
using (var connection = new SqlConnection(ConnectionString))
@ -150,7 +152,7 @@ public class GroupRepository : Repository<Group, Guid>, IGroupRepository
public async Task ReplaceAsync(Group obj, IEnumerable<CollectionAccessSelection> collections)
{
var objWithCollections = JsonSerializer.Deserialize<GroupWithCollections>(JsonSerializer.Serialize(obj));
var objWithCollections = JsonSerializer.Deserialize<GroupWithCollections>(JsonSerializer.Serialize(obj))!;
objWithCollections.Collections = collections.ToArrayTVP();
using (var connection = new SqlConnection(ConnectionString))

View File

@ -9,6 +9,8 @@ using Dapper;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Logging;
#nullable enable
namespace Bit.Infrastructure.Dapper.Repositories;
public class OrganizationRepository : Repository<Organization, Guid>, IOrganizationRepository
@ -18,16 +20,12 @@ public class OrganizationRepository : Repository<Organization, Guid>, IOrganizat
public OrganizationRepository(
GlobalSettings globalSettings,
ILogger<OrganizationRepository> logger)
: this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
: base(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{
_logger = logger;
}
public OrganizationRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString, readOnlyConnectionString)
{ }
public async Task<Organization> GetByIdentifierAsync(string identifier)
public async Task<Organization?> GetByIdentifierAsync(string identifier)
{
using (var connection = new SqlConnection(ConnectionString))
{
@ -104,7 +102,7 @@ public class OrganizationRepository : Repository<Organization, Guid>, IOrganizat
}
}
public async Task<Organization> GetByLicenseKeyAsync(string licenseKey)
public async Task<Organization?> GetByLicenseKeyAsync(string licenseKey)
{
using (var connection = new SqlConnection(ConnectionString))
{
@ -117,7 +115,7 @@ public class OrganizationRepository : Repository<Organization, Guid>, IOrganizat
}
}
public async Task<SelfHostedOrganizationDetails> GetSelfHostedOrganizationDetailsById(Guid id)
public async Task<SelfHostedOrganizationDetails?> GetSelfHostedOrganizationDetailsById(Guid id)
{
using (var connection = new SqlConnection(ConnectionString))
{

View File

@ -13,6 +13,8 @@ using Bit.Infrastructure.Dapper.AdminConsole.Helpers;
using Dapper;
using Microsoft.Data.SqlClient;
#nullable enable
namespace Bit.Infrastructure.Dapper.Repositories;
public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IOrganizationUserRepository
@ -25,7 +27,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
private string _marsConnectionString;
public OrganizationUserRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
: base(globalSettings.SqlServer.ConnectionString, globalSettings.SqlServer.ReadOnlyConnectionString)
{
var builder = new SqlConnectionStringBuilder(ConnectionString)
{
@ -34,10 +36,6 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
_marsConnectionString = builder.ToString();
}
public OrganizationUserRepository(string connectionString, string readOnlyConnectionString)
: base(connectionString, readOnlyConnectionString)
{ }
public async Task<int> GetCountByOrganizationIdAsync(Guid organizationId)
{
using (var connection = new SqlConnection(ConnectionString))
@ -132,7 +130,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
}
}
public async Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, Guid userId)
public async Task<OrganizationUser?> GetByOrganizationAsync(Guid organizationId, Guid userId)
{
using (var connection = new SqlConnection(ConnectionString))
{
@ -172,7 +170,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
}
}
public async Task<Tuple<OrganizationUser, ICollection<CollectionAccessSelection>>> GetByIdWithCollectionsAsync(Guid id)
public async Task<Tuple<OrganizationUser?, ICollection<CollectionAccessSelection>>> GetByIdWithCollectionsAsync(Guid id)
{
using (var connection = new SqlConnection(ConnectionString))
{
@ -183,11 +181,11 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
var user = (await results.ReadAsync<OrganizationUser>()).SingleOrDefault();
var collections = (await results.ReadAsync<CollectionAccessSelection>()).ToList();
return new Tuple<OrganizationUser, ICollection<CollectionAccessSelection>>(user, collections);
return new Tuple<OrganizationUser?, ICollection<CollectionAccessSelection>>(user, collections);
}
}
public async Task<OrganizationUserUserDetails> GetDetailsByIdAsync(Guid id)
public async Task<OrganizationUserUserDetails?> GetDetailsByIdAsync(Guid id)
{
using (var connection = new SqlConnection(ConnectionString))
{
@ -199,7 +197,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
return results.SingleOrDefault();
}
}
public async Task<Tuple<OrganizationUserUserDetails, ICollection<CollectionAccessSelection>>>
public async Task<Tuple<OrganizationUserUserDetails?, ICollection<CollectionAccessSelection>>>
GetDetailsByIdWithCollectionsAsync(Guid id)
{
using (var connection = new SqlConnection(ConnectionString))
@ -211,7 +209,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
var user = (await results.ReadAsync<OrganizationUserUserDetails>()).SingleOrDefault();
var collections = (await results.ReadAsync<CollectionAccessSelection>()).ToList();
return new Tuple<OrganizationUserUserDetails, ICollection<CollectionAccessSelection>>(user, collections);
return new Tuple<OrganizationUserUserDetails?, ICollection<CollectionAccessSelection>>(user, collections);
}
}
@ -224,8 +222,8 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
new { OrganizationId = organizationId },
commandType: CommandType.StoredProcedure);
List<IGrouping<Guid, GroupUser>> userGroups = null;
List<IGrouping<Guid, CollectionUser>> userCollections = null;
List<IGrouping<Guid, GroupUser>>? userGroups = null;
List<IGrouping<Guid, CollectionUser>>? userCollections = null;
var users = results.ToList();
@ -294,7 +292,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
}
}
public async Task<OrganizationUserOrganizationDetails> GetDetailsByUserAsync(Guid userId,
public async Task<OrganizationUserOrganizationDetails?> GetDetailsByUserAsync(Guid userId,
Guid organizationId, OrganizationUserStatusType? status = null)
{
using (var connection = new SqlConnection(ConnectionString))
@ -323,7 +321,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
{
obj.SetNewId();
var objWithCollections = JsonSerializer.Deserialize<OrganizationUserWithCollections>(
JsonSerializer.Serialize(obj));
JsonSerializer.Serialize(obj))!;
objWithCollections.Collections = collections.ToArrayTVP();
using (var connection = new SqlConnection(ConnectionString))
@ -340,7 +338,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
public async Task ReplaceAsync(OrganizationUser obj, IEnumerable<CollectionAccessSelection> collections)
{
var objWithCollections = JsonSerializer.Deserialize<OrganizationUserWithCollections>(
JsonSerializer.Serialize(obj));
JsonSerializer.Serialize(obj))!;
objWithCollections.Collections = collections.ToArrayTVP();
using (var connection = new SqlConnection(ConnectionString))
@ -378,7 +376,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
}
}
public async Task<OrganizationUser> GetByOrganizationEmailAsync(Guid organizationId, string email)
public async Task<OrganizationUser?> GetByOrganizationEmailAsync(Guid organizationId, string email)
{
using (var connection = new SqlConnection(ConnectionString))
{
@ -420,7 +418,7 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
await ReplaceManyAsync(replaceUsers);
}
public async Task<ICollection<Guid>> CreateManyAsync(IEnumerable<OrganizationUser> organizationUsers)
public async Task<ICollection<Guid>?> CreateManyAsync(IEnumerable<OrganizationUser> organizationUsers)
{
if (!organizationUsers.Any())
{

View File

@ -7,6 +7,8 @@ using Bit.Infrastructure.Dapper.Repositories;
using Dapper;
using Microsoft.Data.SqlClient;
#nullable enable
namespace Bit.Infrastructure.Dapper.AdminConsole.Repositories;
public class PolicyRepository : Repository<Policy, Guid>, IPolicyRepository
@ -19,7 +21,7 @@ public class PolicyRepository : Repository<Policy, Guid>, IPolicyRepository
: base(connectionString, readOnlyConnectionString)
{ }
public async Task<Policy> GetByOrganizationIdTypeAsync(Guid organizationId, PolicyType type)
public async Task<Policy?> GetByOrganizationIdTypeAsync(Guid organizationId, PolicyType type)
{
using (var connection = new SqlConnection(ConnectionString))
{

View File

@ -7,6 +7,8 @@ using Bit.Infrastructure.Dapper.Repositories;
using Dapper;
using Microsoft.Data.SqlClient;
#nullable enable
namespace Bit.Infrastructure.Dapper.AdminConsole.Repositories;
public class ProviderOrganizationRepository : Repository<ProviderOrganization, Guid>, IProviderOrganizationRepository
@ -19,7 +21,7 @@ public class ProviderOrganizationRepository : Repository<ProviderOrganization, G
: base(connectionString, readOnlyConnectionString)
{ }
public async Task<ICollection<ProviderOrganization>> CreateManyAsync(IEnumerable<ProviderOrganization> providerOrganizations)
public async Task<ICollection<ProviderOrganization>?> CreateManyAsync(IEnumerable<ProviderOrganization> providerOrganizations)
{
var entities = providerOrganizations.ToList();
@ -74,7 +76,7 @@ public class ProviderOrganizationRepository : Repository<ProviderOrganization, G
}
}
public async Task<ProviderOrganization> GetByOrganizationId(Guid organizationId)
public async Task<ProviderOrganization?> GetByOrganizationId(Guid organizationId)
{
using (var connection = new SqlConnection(ConnectionString))
{

View File

@ -7,6 +7,8 @@ using Bit.Infrastructure.Dapper.Repositories;
using Dapper;
using Microsoft.Data.SqlClient;
#nullable enable
namespace Bit.Infrastructure.Dapper.AdminConsole.Repositories;
public class ProviderRepository : Repository<Provider, Guid>, IProviderRepository
@ -19,7 +21,7 @@ public class ProviderRepository : Repository<Provider, Guid>, IProviderRepositor
: base(connectionString, readOnlyConnectionString)
{ }
public async Task<Provider> GetByOrganizationIdAsync(Guid organizationId)
public async Task<Provider?> GetByOrganizationIdAsync(Guid organizationId)
{
using (var connection = new SqlConnection(ConnectionString))
{

View File

@ -8,6 +8,8 @@ using Bit.Infrastructure.Dapper.Repositories;
using Dapper;
using Microsoft.Data.SqlClient;
#nullable enable
namespace Bit.Infrastructure.Dapper.AdminConsole.Repositories;
public class ProviderUserRepository : Repository<ProviderUser, Guid>, IProviderUserRepository
@ -59,7 +61,7 @@ public class ProviderUserRepository : Repository<ProviderUser, Guid>, IProviderU
}
}
public async Task<ProviderUser> GetByProviderUserAsync(Guid providerId, Guid userId)
public async Task<ProviderUser?> GetByProviderUserAsync(Guid providerId, Guid userId)
{
using (var connection = new SqlConnection(ConnectionString))
{