public async Task ExecuteWithIdentityUpdateAsync_JsonInsertForGenericSubmission_DoesNotThrowException() { var providerFactory = new SqlClientProviderFactory(new DataAnnotationsDefinitionProvider()); var cancellationToken = CancellationToken.None; await using (var provider = providerFactory.Create(ConfigurationRoot.GetConnectionString("OrmTestDb"))) { var identityRepository = new EntityRepository <DomainIdentity, DomainIdentityRow>(provider, this.mapper); var domainIdentity = await identityRepository.FirstOrDefaultAsync( Query.Select <DomainIdentity>() .Where(set => set.AreEqual(identity => identity.UniqueIdentifier, Environment.UserName)), cancellationToken) .ConfigureAwait(false) ?? await identityRepository.SaveAsync( new DomainIdentity(Environment.UserName) { FirstName = "King", MiddleName = "T.", LastName = "Animal" }, cancellationToken) .ConfigureAwait(false); var expected = new GenericSubmission("My Submission", domainIdentity); var internalId = new Field { Name = "Internal ID", Description = "Unique ID used internally" }; var firstName = new Field { Name = "First Name", Description = "The person's first name" }; var lastName = new Field { Name = "Last Name", Description = "The person's last name" }; var yearlyWage = new Field { Name = "Yearly Wage", Description = "The base wage paid year over year." }; var hireDate = new Field { Name = "Hire Date", Description = "The date and time of hire for the person" }; var bonusTarget = new Field { Name = "Bonus Target", Description = "The target bonus for the person" }; var contactNumbers = new Field { Name = "Contact Numbers", Description = "A list of contact numbers for the person in order of preference" }; expected.SetValue(internalId, 9234); expected.SetValue(firstName, "Dan"); expected.SetValue(lastName, "The Man"); expected.SetValue(yearlyWage, 75100.35m); expected.SetValue(hireDate, DateTimeOffset.Now); expected.SetValue(bonusTarget, 1.59834578934); expected.SetValue( contactNumbers, new List <string> { "423-222-2252", "615-982-0012", "+1-555-252-5521" }); expected.Submit(); var fieldRepository = new EntityRepository <Field, FieldRow>(provider, this.mapper); // TODO: Return names only from the repo as a dynamic var fields = expected.SubmissionValues.Select(value => value.Field).Distinct().ToDictionary(field => field.Name, field => field); var inclusionValues = fields.Keys.ToArray(); var existingFields = new List <Field>(); await foreach (var item in fieldRepository.SelectEntitiesAsync( new EntitySelection <Field>().Where(set => set.Include(field => field.Name, inclusionValues)), cancellationToken) .ConfigureAwait(false)) { existingFields.Add(item); } foreach (var field in existingFields) { var output = fields[field.Name]; this.mapper.MapTo(field, output); } foreach (var field in fields.Values.Where(field => field.FieldId.HasValue == false)) { await fieldRepository.SaveAsync(field, cancellationToken).ConfigureAwait(false); } var submissionRepository = new EntityRepository <GenericSubmission, GenericSubmissionRow>(provider, this.mapper); var transaction = await provider.BeginTransactionAsync(cancellationToken).ConfigureAwait(false); await submissionRepository.SaveAsync(expected, cancellationToken).ConfigureAwait(false); var submissionId = expected.GenericSubmissionId.GetValueOrDefault(); Assert.AreNotEqual(0, submissionId); // Do the field values var valuesList = from v in expected.SubmissionValues select new FieldValueTableTypeRow { FieldId = v.Field.FieldId.GetValueOrDefault(), LastModifiedByDomainIdentifierId = domainIdentity.DomainIdentityId.GetValueOrDefault(), LastModifiedTime = expected.SubmittedTime }; var valuesCommand = new JsonInsert <FieldValueRow>(provider.DatabaseContext).SelectFromInserted(); var insertedValues = new List <FieldValueRow>(); await foreach (var item in valuesCommand.ExecuteForResultsAsync(valuesList, cancellationToken).ConfigureAwait(false)) { insertedValues.Add(item); } // Map back to the domain object. foreach (var value in expected.SubmissionValues) { var input = insertedValues.FirstOrDefault(row => row.FieldId == value.Field.FieldId); this.mapper.MapTo(input, value); } // Do the field value elements var elementsList = (from e in expected.SubmissionValues.SelectMany(value => value.Elements) select new FieldValueElementTableTypeRow { FieldValueElementId = e.FieldValueElementId, FieldValueId = e.FieldValue.FieldValueId.GetValueOrDefault(), Order = e.Order, DateElement = e.Element as DateTimeOffset? ?? e.Element as DateTime?, FloatElement = e.Element as double? ?? e.Element as float?, IntegerElement = e.Element as long? ?? e.Element as int? ?? e.Element as short? ?? e.Element as byte?, MoneyElement = e.Element as decimal?, TextElement = e.Element as string // here we actually want it to be null if it is not a string }).ToList(); var elementsCommand = new JsonInsert <FieldValueElementRow>(provider.DatabaseContext).SelectFromInserted(); // Reassign with our added identities // TODO: create dictionary for seeks var insertedElementRows = new List <FieldValueElementRow>(); await foreach (var item in elementsCommand.ExecuteForResultsAsync(elementsList, cancellationToken).ConfigureAwait(false)) { insertedElementRows.Add(item); } foreach (var element in elementsList) { var input = insertedElementRows.First(row => row.FieldValueId == element.FieldValueId && row.Order == element.Order); this.mapper.MapTo(input, element); } var dateElementsCommand = new JsonInsert <DateElementRow>(provider.DatabaseContext) .InsertInto(row => row.DateElementId, row => row.Value) .From <FieldValueElementTableTypeRow>(row => row.FieldValueElementId, row => row.DateElement); await dateElementsCommand.ExecuteAsync(elementsList.Where(row => row.DateElement.HasValue), cancellationToken).ConfigureAwait(false); var floatElementsCommand = new JsonInsert <FloatElementRow>(provider.DatabaseContext) .InsertInto(row => row.FloatElementId, row => row.Value) .From <FieldValueElementTableTypeRow>(row => row.FieldValueElementId, row => row.FloatElement); await floatElementsCommand.ExecuteAsync(elementsList.Where(row => row.FloatElement.HasValue), cancellationToken) .ConfigureAwait(false); var integerElementsCommand = new JsonInsert <IntegerElementRow>(provider.DatabaseContext) .InsertInto(row => row.IntegerElementId, row => row.Value) .From <FieldValueElementTableTypeRow>(row => row.FieldValueElementId, row => row.IntegerElement); await integerElementsCommand.ExecuteAsync(elementsList.Where(row => row.IntegerElement.HasValue), cancellationToken) .ConfigureAwait(false); var moneyElementsCommand = new JsonInsert <MoneyElementRow>(provider.DatabaseContext) .InsertInto(row => row.MoneyElementId, row => row.Value) .From <FieldValueElementTableTypeRow>(row => row.FieldValueElementId, row => row.MoneyElement); await moneyElementsCommand.ExecuteAsync(elementsList.Where(row => row.MoneyElement.HasValue), cancellationToken) .ConfigureAwait(false); var textElementsCommand = new JsonInsert <TextElementRow>(provider.DatabaseContext) .InsertInto(row => row.TextElementId, row => row.Value) .From <FieldValueElementTableTypeRow>(row => row.FieldValueElementId, row => row.TextElement); await textElementsCommand.ExecuteAsync(elementsList.Where(row => row.TextElement != null), cancellationToken).ConfigureAwait(false); // Attach the values to the submission var genericValueSubmissions = from v in insertedValues select new GenericSubmissionValueTableTypeRow { GenericSubmissionId = submissionId, GenericSubmissionValueId = v.FieldValueId }; var submissionCommand = new JsonInsert <GenericSubmissionValueRow>(provider.DatabaseContext); await submissionCommand.ExecuteAsync(genericValueSubmissions, cancellationToken).ConfigureAwait(false); await transaction.CommitAsync(cancellationToken).ConfigureAwait(false); } }
public async Task ExecuteAsyncJsonInsertForFields_DoesNotThrowException() { var internalId = new Field { Name = "INS_Internal ID", Description = "Unique ID used internally" }; var firstName = new Field { Name = "INS_First Name", Description = "The person's first name" }; var lastName = new Field { Name = "INS_Last Name", Description = "The person's last name" }; var yearlyWage = new Field { Name = "INS_Yearly Wage", Description = "The base wage paid year over year." }; var hireDate = new Field { Name = "INS_Hire Date", Description = "The date and time of hire for the person" }; var bonusTarget = new Field { Name = "INS_Bonus Target", Description = "The target bonus for the person" }; var contactNumbers = new Field { Name = "INS_Contact Numbers", Description = "A list of contact numbers for the person in order of preference" }; var fields = new List <Field> { internalId, firstName, lastName, yearlyWage, hireDate, bonusTarget, contactNumbers }; var providerFactory = new SqlClientProviderFactory(new DataAnnotationsDefinitionProvider()); var cancellationToken = CancellationToken.None; await using (var provider = providerFactory.Create(ConfigurationRoot.GetConnectionString("OrmTestDb"))) { var transaction = await provider.BeginTransactionAsync(cancellationToken).ConfigureAwait(false); var fieldRepository = new EntityRepository <Field, FieldRow>(provider, this.mapper); var fieldValueRepository = new EntityRepository <FieldValue, FieldValueRow>(provider, this.mapper); // Delete the existing rows. var fieldSelection = Query.Select <FieldRow>().Where(set => set.AreEqual(row => row.Name, "INS_%")); var existingFields = new List <Field>(); await foreach (var item in fieldRepository.SelectEntitiesAsync(fieldSelection, cancellationToken).ConfigureAwait(false)) { existingFields.Add(item); } if (existingFields.Any()) { await fieldValueRepository.DeleteSelectionAsync( Query.Select <FieldValueRow>() .Where(set => set.Include(row => row.FieldId, existingFields.Select(field => field.FieldId).ToArray())), cancellationToken) .ConfigureAwait(false); await fieldRepository.DeleteSelectionAsync(fieldSelection, cancellationToken).ConfigureAwait(false); } var fieldInsertCommand = new JsonInsert <FieldRow>(provider.DatabaseContext); await fieldInsertCommand.ExecuteAsync( fields.Select( field => new FieldTableTypeRow { Name = field.Name, Description = field.Description }), cancellationToken) .ConfigureAwait(false); await transaction.CommitAsync(cancellationToken).ConfigureAwait(false); } }