diff --git a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/EntityIds.cs b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/EntityIds.cs
index a0061964..fcbd0df7 100644
--- a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/EntityIds.cs
+++ b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/EntityIds.cs
@@ -51,7 +51,7 @@ IEnumerator IEnumerable.GetEnumerator()
///
/// Creates a view of these Ids that auto-casts every Id into a model of the given model type
///
- Entities AsModels(IDb db)
+ public Entities AsModels(IDb db)
where TModel : IReadOnlyModel
{
return new Entities(this, db);
diff --git a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValueEntities.cs b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValueEntities.cs
new file mode 100644
index 00000000..c25c858c
--- /dev/null
+++ b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValueEntities.cs
@@ -0,0 +1,46 @@
+using System.Collections;
+using System.Collections.Generic;
+using NexusMods.MnemonicDB.Abstractions.Models;
+
+namespace NexusMods.MnemonicDB.Abstractions.IndexSegments;
+
+///
+/// A wrapper around Values that auto-creates the given ReadModel on-the-fly
+///
+public readonly struct ValueEntities : IReadOnlyCollection
+ where TModel : IReadOnlyModel
+{
+ private readonly Values _values;
+
+ ///
+ /// The database the models are read from
+ ///
+ private IDb Db { get; }
+
+ ///
+ /// Creates a new ValueEntities, from the given values, database, and entity id
+ ///
+ public ValueEntities(Values values, IDb db)
+ {
+ _values = values;
+ Db = db;
+ }
+
+ ///
+ public IEnumerator GetEnumerator()
+ {
+ foreach (var value in _values)
+ {
+ yield return TModel.Create(Db, value);
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+
+ ///
+ public int Count => _values.Count;
+}
diff --git a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValuesExtensions.cs b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValuesExtensions.cs
index 37b43a41..d7d48eb4 100644
--- a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValuesExtensions.cs
+++ b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValuesExtensions.cs
@@ -15,4 +15,13 @@ public static Entities, TModel> As(this Values, TModel>(ids, db);
}
+
+ ///
+ /// Returns a view of the values as models whose ids are the given id
+ ///
+ public static ValueEntities AsModels(this Values values, IDb db)
+ where TModel : IReadOnlyModel
+ {
+ return new ValueEntities(values, db);
+ }
}
diff --git a/src/NexusMods.MnemonicDB.SourceGenerator/Template.weave b/src/NexusMods.MnemonicDB.SourceGenerator/Template.weave
index 6a7fe926..800f3c4b 100644
--- a/src/NexusMods.MnemonicDB.SourceGenerator/Template.weave
+++ b/src/NexusMods.MnemonicDB.SourceGenerator/Template.weave
@@ -265,7 +265,7 @@ public partial class {{= model.Name}} {
{{each attr in model.Attributes}}
{{if attr.IsCollection && attr.IsReference && !attr.IsMarker}}
public __SEGMENTS__.Values<__ABSTRACTIONS__.EntityId, ulong> {{= attr.ContextualName}} => {{= attr.FieldName}}.Get(this);
- public IEnumerable<{{= attr.ReferenceType.ToDisplayString()}}.ReadOnly> {{= attr.Name}} => {{= attr.FieldName}}.Get(this).Select(id => new {{= attr.ReferenceType.ToDisplayString()}}.ReadOnly(Db, id));
+ public __SEGMENTS__.ValueEntities<{{= attr.ReferenceType.ToDisplayString()}}.ReadOnly> {{= attr.Name}} => __SEGMENTS__.ValuesExtensions.AsModels<{{= attr.ReferenceType.ToDisplayString()}}.ReadOnly>({{= attr.FieldName}}.Get(this), Db);
{{elif attr.IsMarker}}
public bool Is{{= attr.ContextualName}} => {{= attr.FieldName}}.Contains(this);
{{else}}
@@ -281,7 +281,7 @@ public partial class {{= model.Name}} {
{{each backref in model.BackReferences}}
- public __SEGMENTS__.Entities<{{= backref.OtherModel.ToDisplayString()}}.ReadOnly> {{= backref.Name}} => Db.GetBackRefs({{= backref.OtherAttribute.ToDisplayString()}}, this.Id).AsModels<{{= backRef.OtherModel.ToDisplayString()}}.ReadOnly>(Db);
+ public __SEGMENTS__.Entities<{{= backref.OtherModel.ToDisplayString()}}.ReadOnly> {{= backref.Name}} => Db.GetBackRefs({{= backref.OtherAttribute.ToDisplayString()}}, this.Id).AsModels<{{= backref.OtherModel.ToDisplayString()}}.ReadOnly>(Db);
{{/each}}
///
diff --git a/tests/NexusMods.MnemonicDB.Tests/DbTests.cs b/tests/NexusMods.MnemonicDB.Tests/DbTests.cs
index e9d9ad97..608890d8 100644
--- a/tests/NexusMods.MnemonicDB.Tests/DbTests.cs
+++ b/tests/NexusMods.MnemonicDB.Tests/DbTests.cs
@@ -281,7 +281,7 @@ public async Task CanGetDatomsFromEntity()
mod.Contains(Mod.Source).Should().BeTrue();
mod.Contains(Loadout.Name).Should().BeFalse();
- mod.ToString().Should().Be("Mod<200000000000002>");
+ mod.ToString().Should().Be("Mod");
await VerifyTable(mod);
}