private static async Task <TEntity> GetOrCreateEntityAsync <TEntity>(NesteoDbContext dbContext, Expression <Func <TEntity, bool> > predicate, Func <TEntity> factoryFunc) where TEntity : class { // Get db set DbSet <TEntity> dbSet = dbContext.Set <TEntity>(); // If the entity exists in the local snapshot, return it directly TEntity entity = dbSet.Local.FirstOrDefault(predicate.Compile()); if (entity != null) { return(entity); } // Search the entity in the database entity = await dbSet.FirstOrDefaultAsync(predicate).ConfigureAwait(false); if (entity != null) { return(entity); } // Entity doesn't exist yet. Create a new one entity = factoryFunc.Invoke(); return(dbSet.Add(entity).Entity); }
public RegionService(NesteoDbContext dbContext, IMapper mapper) : base(dbContext, mapper) { }
public NestingBoxService(NesteoDbContext dbContext, IMapper mapper, INestingBoxIdGenerator nestingBoxIdGenerator) : base(dbContext, mapper) { _nestingBoxIdGenerator = nestingBoxIdGenerator ?? throw new ArgumentNullException(nameof(nestingBoxIdGenerator)); }
public OwnerService(NesteoDbContext dbContext, IMapper mapper) : base(dbContext, mapper) { }
private static async Task <int> ImportCsvFileAsync <TRecord>(NesteoDbContext dbContext, string filePath) { using var fileReader = new StreamReader(filePath); using var csvReader = new CsvReader(fileReader); // File is expected to have a header csvReader.Configuration.HasHeaderRecord = true; // Set field delimiter csvReader.Configuration.Delimiter = ","; // Don't throw errors when fields are empty/missing. csvReader.Configuration.MissingFieldFound = null; // Match header names case insensitively csvReader.Configuration.PrepareHeaderForMatch = (header, index) => header.ToLower(); // Validate header Console.WriteLine("Validating file header..."); csvReader.Read(); csvReader.ReadHeader(); csvReader.ValidateHeader <TRecord>(); Console.WriteLine($"Importing data from {filePath} ..."); var exceptions = 0; var fileLineNumber = 1; foreach (TRecord record in csvReader.GetRecords <TRecord>()) { fileLineNumber++; Console.WriteLine($"Importing line {fileLineNumber}: {record.GetType().Name} {{{Utils.SerializeObjectProperties(record)}}}"); try { switch (record) { case NestingBoxRecord nestingBoxRecord: await ImportNestingBoxRecordAsync(dbContext, nestingBoxRecord).ConfigureAwait(false); break; case InspectionRecord inspectionRecord: await ImportInspectionRecordAsync(dbContext, inspectionRecord).ConfigureAwait(false); break; default: throw new InvalidOperationException($"Unexpected record type: {record.GetType()}"); } } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($" !! Import failed: {ex.Message}"); Console.ResetColor(); exceptions++; } } return(exceptions); }
private static async Task SaveDatabaseAsync(NesteoDbContext dbContext) { Console.WriteLine("Saving changes to database..."); await dbContext.SaveChangesAsync().ConfigureAwait(false); }
private static async Task ImportInspectionRecordAsync(NesteoDbContext dbContext, InspectionRecord inspectionRecord) { // Create collection for comments var comments = new List <string>(); if (!string.IsNullOrWhiteSpace(inspectionRecord.Comments)) { comments.AddRange(inspectionRecord.Comments.Split(',').Select(c => c.Trim()).Where(c => !string.IsNullOrEmpty(c))); } // Get nesting box entity NestingBoxEntity nestingBoxEntity = await dbContext.NestingBoxes.FindAsync(inspectionRecord.NestingBoxId).ConfigureAwait(false); if (nestingBoxEntity == null) { throw new InvalidCsvRecordException($"Nesting box {inspectionRecord.NestingBoxId} doesn't exist."); } // Ensure the species entity exists SpeciesEntity speciesEntity = null; if (!string.IsNullOrWhiteSpace(inspectionRecord.SpeciesName) && !new[] { "unbestimmt", "unbekannt" }.Contains(inspectionRecord.SpeciesName.ToLower())) { speciesEntity = await GetOrCreateEntityAsync(dbContext, species => species.Name == inspectionRecord.SpeciesName, () => new SpeciesEntity { Name = inspectionRecord.SpeciesName }).ConfigureAwait(false); } // Analyze date info DateTime inspectionDate = string.IsNullOrWhiteSpace(inspectionRecord.Date) ? throw new InvalidCsvRecordException("Inspection date not set.") : ParseDate(inspectionRecord.Date); // Map nesting box condition (Condition condition, bool justRepaired) = GetCondition(inspectionRecord.Condition); if (condition != Condition.Good) { comments.Add($"Kasten-Zustand: {inspectionRecord.Condition}"); } // Analyze ringing activity (ParentBirdDiscovery femaleParentBirdDiscovery, ParentBirdDiscovery maleParentBirdDiscovery, int ringedChickCount) = AnalyzeRingingActivity(inspectionRecord.RingedCount); // Create inspection dbContext.Inspections.Add(new InspectionEntity { NestingBox = nestingBoxEntity, InspectionDate = inspectionDate, InspectedByUser = null, HasBeenCleaned = GetYesNo(inspectionRecord.HasBeenCleaned), Condition = condition, JustRepaired = justRepaired, Occupied = GetYesNoWithUnknown(inspectionRecord.Occupied), ContainsEggs = !string.IsNullOrWhiteSpace(inspectionRecord.EggCount), EggCount = ParseNumberWithUnknown(inspectionRecord.EggCount), ChickCount = ParseNumberWithUnknown(inspectionRecord.ChickCount), RingedChickCount = ringedChickCount, AgeInDays = ParseNumberWithUnknown(inspectionRecord.ChickAges), FemaleParentBirdDiscovery = femaleParentBirdDiscovery, MaleParentBirdDiscovery = maleParentBirdDiscovery, Species = speciesEntity, ImageFileName = null, Comment = comments.Any() ? string.Join(", ", comments) : null, LastUpdated = inspectionDate }); }
private static async Task ImportNestingBoxRecordAsync(NesteoDbContext dbContext, NestingBoxRecord nestingBoxRecord) { // Check id length if (nestingBoxRecord.Id.Length != 6) { throw new InvalidCsvRecordException("Id length is invalid. Expected 6 characters."); } // Ensure the nesting box doesn't exist yet if (await dbContext.NestingBoxes.FindAsync(nestingBoxRecord.Id).ConfigureAwait(false) != null) { throw new InvalidCsvRecordException("Nesting box exists and should not be overwritten."); } // Create collection for comments var comments = new List <string>(); if (!string.IsNullOrWhiteSpace(nestingBoxRecord.Comments)) { comments.AddRange(nestingBoxRecord.Comments.Split(',').Select(c => c.Trim()).Where(c => !string.IsNullOrEmpty(c))); } // Ensure the owner entity exists OwnerEntity ownerEntity = await GetOrCreateEntityAsync(dbContext, owner => owner.Name == nestingBoxRecord.OwnerName, () => new OwnerEntity { Name = nestingBoxRecord.OwnerName }).ConfigureAwait(false); // Ensure the region entity exists string regionName = $"{nestingBoxRecord.RegionCityName} - {nestingBoxRecord.RegionDetailedName}"; string ExtractIdPrefix() => nestingBoxRecord.Id[0].ToString(); RegionEntity regionEntity = await GetOrCreateEntityAsync(dbContext, region => region.Name == regionName, () => new RegionEntity { Name = regionName, NestingBoxIdPrefix = ExtractIdPrefix() }).ConfigureAwait(false); // Map material type var material = Material.Other; if (!string.IsNullOrWhiteSpace(nestingBoxRecord.Material)) { material = GetMaterial(nestingBoxRecord.Material); if (material == Material.Other) { comments.Add($"Material: {nestingBoxRecord.Material}"); } } // Map hole size var holeSize = HoleSize.Other; if (!string.IsNullOrWhiteSpace(nestingBoxRecord.HoleSize)) { holeSize = GetHoleSize(nestingBoxRecord.HoleSize); if (holeSize == HoleSize.Other) { comments.Add($"Lochgröße: {nestingBoxRecord.HoleSize}"); } } // Convert UTM to decimal coordinates Coordinate coordinate = null; if (!string.IsNullOrWhiteSpace(nestingBoxRecord.UtmEast) && !string.IsNullOrWhiteSpace(nestingBoxRecord.UtmNorth)) { var utm = new UniversalTransverseMercator(UtmLatZ, UtmLongZ, double.Parse(nestingBoxRecord.UtmEast), double.Parse(nestingBoxRecord.UtmNorth)); coordinate = UniversalTransverseMercator.ConvertUTMtoLatLong(utm); } // Analyze date info DateTime?hangUpDate = null; if (!string.IsNullOrWhiteSpace(nestingBoxRecord.HangUpDate)) { hangUpDate = ParseDate(nestingBoxRecord.HangUpDate); if (hangUpDate.Value.Date == new DateTime(1999, 1, 1)) { hangUpDate = null; } } // Create nesting box dbContext.NestingBoxes.Add(new NestingBoxEntity { Id = nestingBoxRecord.Id, Region = regionEntity, OldId = null, ForeignId = string.IsNullOrWhiteSpace(nestingBoxRecord.ForeignId) ? null : nestingBoxRecord.ForeignId, CoordinateLongitude = coordinate?.Longitude.DecimalDegree, CoordinateLatitude = coordinate?.Latitude.DecimalDegree, HangUpDate = hangUpDate, HangUpUser = null, Owner = ownerEntity, Material = material, HoleSize = holeSize, ImageFileName = null, Comment = comments.Any() ? string.Join(", ", comments) : null, LastUpdated = string.IsNullOrWhiteSpace(nestingBoxRecord.DataUpdateDate) ? hangUpDate ?? DateTime.UtcNow : ParseDate(nestingBoxRecord.DataUpdateDate) }); }
public SpeciesService(NesteoDbContext dbContext, IMapper mapper) : base(dbContext, mapper) { }
public InspectionService(NesteoDbContext dbContext, IMapper mapper, ILateDependency <INestingBoxService> nestingBoxServiceDependency) : base(dbContext, mapper) { _nestingBoxServiceDependency = nestingBoxServiceDependency ?? throw new ArgumentNullException(nameof(nestingBoxServiceDependency)); }
protected CrudServiceBase(NesteoDbContext dbContext, IMapper mapper) { DbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); Mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); Entities = dbContext.Set <TEntity>(); }