Created
March 15, 2022 14:13
-
-
Save johnknoop/6868d069b6ff23486614f8195d936f44 to your computer and use it in GitHub Desktop.
Polymorphic model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace DeviceService.Api.Contracts; | |
public record DeviceMetadata(Guid MetadataFieldId, System.Text.Json.JsonElement Value); | |
public record DeviceToCreate(Guid DeviceTypeId, string DeviceName, IList<DeviceMetadata> MetaData); | |
public record BulkCreateDevicesRequest(IList<DeviceToCreate> Devices); | |
/* | |
Example: | |
{ | |
"devices": [ | |
{ | |
"deviceTypeId": "23423f-4g65465-ase4ts5vg-56ey56e", | |
"name": "Kullen 1", | |
"metadata": [ | |
{ | |
"metadataFieldId": "23423f-4g65465-ase4ts5vg-56ey56e", | |
"value": 23.543 | |
}, | |
{ | |
"metadataFieldId": "23423f-4g65465-ase4ts5vg-56ey56e", | |
"value": "2022-01-01" | |
}, | |
{ | |
"metadataFieldId": "23423f-4g65465-ase4ts5vg-56ey56e", | |
"value": false | |
} | |
] | |
} | |
] | |
} | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
IDictionary<Guid, Domain.Metadata.MetadataFieldBase> LoadMetadataFieldsFromDatabase(ICollection<Guid> metadataFieldIds) | |
{ | |
// Here we wanna do dbContext.MetadataFields.Where(x => metadataFieldIds.Contains(x.Id)) | |
} | |
IDictionary<Guid, DeviceType> LoadDeviceTypesFromDatabase(ICollection<Guid> deviceTypeIds) | |
{ | |
// Here we wanna do dbContext.DeviceTypes.Where(x => deviceTypeIds.Contains(x.Id)) | |
} | |
[HttpPost("bulk/create")] | |
public async Task BulkCreateDevices(BulkCreateDevicesRequest request) | |
{ | |
// Load all the referenced metadatafields upfront for performance reasons: | |
var metadataFieldsReferenced = LoadMetadataFieldsFromDatabase(request.Devices.SelectMany(x => x.MetaData.Select(y => y.MetadataFieldId)).ToList()); | |
// Load all the referenced device types upfront for performance reasons: | |
var allReferencedDeviceTypes = LoadDeviceTypesFromDatabase(request.Devices.Select(x => x.DeviceTypeId).ToList()); | |
var devicesToInsert = request.Devices.Select(d => | |
new Device( | |
name: d.DeviceName, | |
deviceType: allReferencedDeviceTypes[d.DeviceTypeId], | |
metadata: d.MetaData.Select<DeviceMetadata, MetadataFieldValueBase>(m => { | |
return metadataFieldsReferenced.TryGetValue(m.MetadataFieldId, out var referencedField) | |
? referencedField switch { | |
StringMetadataField field => field.CreateValue(new Guid(), m.Value.GetString()), | |
IntMetadataField field => field.CreateValue(new Guid(), m.Value.GetInt32()), | |
_ => throw new NotImplementedException("todo: cover all the types") | |
} | |
: throw new Exception(""); | |
}).ToList() | |
) | |
); | |
// await db.Context.InsertAsync(devicesToInsert) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using DeviceService.Domain.Types; | |
namespace DeviceService.Domain.Metadata; | |
#region Fields | |
public abstract class MetadataFieldBase | |
{ | |
protected MetadataFieldBase(Guid id, string name) | |
{ | |
Id = id; | |
Name = name; | |
} | |
public Guid Id { get; private set; } | |
public string Name { get; private set; } | |
} | |
public class StringMetadataField : MetadataFieldBase | |
{ | |
public StringMetadataField(Guid id, string name) : base(id, name) { } | |
public StringMetadataValue CreateValue(Guid id, string value) | |
{ | |
return new StringMetadataValue(id, value); | |
} | |
} | |
public class IntMetadataField : MetadataFieldBase | |
{ | |
public IntMetadataField(string unitOfMeasure, Guid id, string name) : base(id, name) | |
{ | |
UnitOfMeasure = unitOfMeasure; | |
} | |
public string UnitOfMeasure { get; private set; } | |
public int MinValue { get; private set; } | |
public IntMetadataValue CreateValue(Guid id, int value) | |
{ | |
if (value < MinValue) { | |
throw new Exception("Ajabaja"); | |
} | |
return new IntMetadataValue(id, value); | |
} | |
} | |
public class DateMetadataField : MetadataFieldBase | |
{ | |
public DateMetadataField(Guid id, string name) : base(id, name) { } | |
} | |
#endregion | |
#region Values | |
public abstract class MetadataFieldValueBase | |
{ | |
protected MetadataFieldValueBase(Guid id) | |
{ | |
Id = id; | |
} | |
public Guid Id { get; private set; } | |
} | |
public class StringMetadataValue : MetadataFieldValueBase | |
{ | |
internal StringMetadataValue(Guid id, string value) : base(id) | |
{ | |
Value = value; | |
} | |
public string Value { get; private set; } | |
} | |
public class IntMetadataValue : MetadataFieldValueBase | |
{ | |
internal IntMetadataValue(Guid id, int value) : base(id) | |
{ | |
Value = value; | |
} | |
public int Value { get; private set; } | |
} | |
public class DateMetadataValue : MetadataFieldValueBase | |
{ | |
internal DateMetadataValue(Guid id, DateTime value) : base(id) | |
{ | |
Value = value; | |
} | |
public DateTime Value { get; private set; } | |
} | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment