FMMultiFieldMapper 0.2.0
dotnet add package FMMultiFieldMapper --version 0.2.0
NuGet\Install-Package FMMultiFieldMapper -Version 0.2.0
<PackageReference Include="FMMultiFieldMapper" Version="0.2.0" />
paket add FMMultiFieldMapper --version 0.2.0
#r "nuget: FMMultiFieldMapper, 0.2.0"
// Install FMMultiFieldMapper as a Cake Addin #addin nuget:?package=FMMultiFieldMapper&version=0.2.0 // Install FMMultiFieldMapper as a Cake Tool #tool nuget:?package=FMMultiFieldMapper&version=0.2.0
FileMaker MultiField mapper
This library maps data between FileMaker-based DTO objects and relational database objects. The focus is on multi-fields that are easily filterable.
Installation
You can install the library via NuGet:
dotnet add package FMMultiFieldMapper
Sample Usage
Implementing FmMultiFieldMap
To use the FmMultiFieldMapper
, you need to implement the abstract FmMultiFieldMap
class.
internal class InMemoryFmMultiFieldMapper(TestContext context) : FmMultiFieldMap
{
public override async Task<int> GetOrCreateMultiFieldId(string name)
{
var id = await context.Multifields
.Where(x => x.Name == name)
.Select(s => s.FmMultiFieldId)
.FirstOrDefaultAsync();
if (id == 0)
{
var multifield = new FmMultiField() { Name = name };
context.Multifields.Add(multifield);
await context.SaveChangesAsync();
id = multifield.FmMultiFieldId;
}
return id;
}
public override async Task<int> GetOrCreateMultiFieldValueId(int multifieldId, string value)
{
var id = await context.MultifieldValues
.Where(x => x.FmMultiFieldId == multifieldId && x.Value == value)
.Select(s => s.FmMultiFieldValueId)
.FirstOrDefaultAsync();
if (id == 0)
{
var multifieldValue = new FmMultiFieldValue()
{
FmMultiFieldId = multifieldId,
Value = value
};
context.MultifieldValues.Add(multifieldValue);
await context.SaveChangesAsync();
id = multifieldValue.FmMultiFieldValueId;
}
return id;
}
}
Mapping FileMaker Objects to Relational Database Objects
Below is an example of how to map a FileMaker object (FmSourceTestClass) to a relational database object (FmTargetTestClassMultifield).
[DataContract(Name = "TestLayout")]
public class FmSourceTestClass
{
[NotMapped]
public int FileMakerRecordId { get; set; }
[DataMember(Name = "Themen(1)")]
[FileMakerMultiField(MultiFieldName = "Themen", Order = 0)]
public string? Themen1 { get; set; }
[DataMember(Name = "Themen(2)")]
[FileMakerMultiField(MultiFieldName = "Themen", Order = 1)]
public string? Themen2 { get; set; }
[DataMember(Name = "Themen(3)")]
[FileMakerMultiField(MultiFieldName = "Themen", Order = 2)]
public string? Themen3 { get; set; }
}
public class FmTargetTestClassMultifield : IFmTargetMultiField
{
public int FmTargetTestClassMultifieldId { get; set; }
public int FmMultiFieldId { get; set; }
public FmMultiField? FmMultiField { get; set; }
public int FmMultiFieldValueId { get; set; }
public FmMultiFieldValue? FmMultiFieldValue { get; set; }
public int FmTargetTestClassId { get; set; }
public FmTargetTestClass? FmTargetTestClass { get; set; }
public int Order { get; set; }
}
var target = _dbContext.FmTargetTestClasses.FirstOrDefault();
var source = new FmSourceTestClass()
{
Themen1 = "Test3",
Themen2 = "Test4",
Themen3 = "Test5"
};
InMemoryFmMultiFieldMapper mapper = new(_dbContext);
await mapper.Map(source, target.FmTargetTestClassMultifields);
_dbContext.SaveChanges();
DTO mapping
You can also map data from a DTO object to your database entities using Dictionary<string, List<string>>
Here's how you can map a FmTargetTestClassDto
to FmTargetTestClass
:
FmTargetTestClassDto dto = new()
{
FmTargetTestClassMultifields = new()
{
{ "Themen", ["Test1", "Test2", "Test3"] },
{ "Was", ["WTest1", "WTest2", "WTest3"] },
}
};
CacheFmMultiFieldMapper mapper = new(_dbContext);
FmTargetTestClass fmTargetTestClass = new();
_dbContext.FmTargetTestClasses.Add(fmTargetTestClass);
_dbContext.SaveChanges();
await mapper.MapFromDtoDictionary(dto.FmTargetTestClassMultifields, fmTargetTestClass.FmTargetTestClassMultifields);
_dbContext.SaveChanges();
var fmTargetTestClassWithIncludes = _dbContext.FmTargetTestClasses
.Include(i => i.FmTargetTestClassMultifields)
.ThenInclude(t => t.FmMultiField)
.Include(i => i.FmTargetTestClassMultifields)
.ThenInclude(t => t.FmMultiFieldValue)
.FirstOrDefault(f => f.Id == fmTargetTestClass.Id);
Assert.IsNotNull(fmTargetTestClassWithIncludes);
Assert.AreEqual(6, fmTargetTestClassWithIncludes.FmTargetTestClassMultifields.Count);
FmTargetTestClassDto testDto = new();
testDto.FmTargetTestClassMultifields = FmMultiFieldMap
.GetDtoDictionary(fmTargetTestClassWithIncludes.FmTargetTestClassMultifields);
Assert.AreEqual(dto.FmTargetTestClassMultifields.Count, testDto.FmTargetTestClassMultifields.Count);
All samples are available in the test project located at .src/FMMultifieldMapperTests
.
FmSyncService
Synchronize IFmObject to IFmDbObject based on FileMakerRecordId, modification date and synchronization date
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please open an issue or submit a pull request. Make sure to follow the coding standards and include tests for any new features or bug fixes.
ChangeLog
<details open="open"><summary>v0.2.0</summary>
- FmMultiFieldMap.GetDtoDictionary added
- FmMultiFieldMap.MapToDtoDictionary marked as Obsolete: Use GetDtoDictionary instead
abstract class FmSyncService
Synchronize IFmObject to IFmDbObject based on FileMakerRecordId, modification date and synchronization date.- FmSyncTests
</details>
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.