diff --git a/docs/documents/querying/linq/index.md b/docs/documents/querying/linq/index.md
index badda06657..a955617407 100644
--- a/docs/documents/querying/linq/index.md
+++ b/docs/documents/querying/linq/index.md
@@ -16,7 +16,7 @@ implements the traditional [IQueryable](https://msdn.microsoft.com/en-us/library
///
IMartenQueryable Query();
```
-snippet source | anchor
+snippet source | anchor
To query for all documents of a type - not that you would do this very often outside of testing - use the `Query()` method like this:
diff --git a/src/LinqTests/Bugs/Bug_3151_using_duplicated_fields_in_linq_queries.cs b/src/LinqTests/Bugs/Bug_3151_using_duplicated_fields_in_linq_queries.cs
new file mode 100644
index 0000000000..8aada84c10
--- /dev/null
+++ b/src/LinqTests/Bugs/Bug_3151_using_duplicated_fields_in_linq_queries.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Marten;
+using Marten.Schema;
+using Marten.Testing.Harness;
+using Shouldly;
+using Xunit.Abstractions;
+
+namespace LinqTests.Bugs;
+
+public class Bug_3151_using_duplicated_fields_in_linq_queries : BugIntegrationContext
+{
+ private readonly ITestOutputHelper _output;
+
+ public Bug_3151_using_duplicated_fields_in_linq_queries(ITestOutputHelper output)
+ {
+ _output = output;
+ }
+
+
+ [Fact]
+ public async Task filtering_by_null_ids_works()
+ {
+ var p1 = new Person { ChildId = Guid.NewGuid()};
+ var p2 = new Person { ChildId = Guid.NewGuid()};
+ theSession.Store(p1,p2);
+ await theSession.SaveChangesAsync();
+ Guid?[] ids = [p1.ChildId];
+ var results = await theSession.Query()
+ .Where(x => x.ChildId.In(ids))
+ .ToListAsync();
+ results.Single().ChildId.ShouldBe(p1.ChildId);
+ }
+
+ [Fact]
+ public async Task filtering_by_non_null_ids_using_value_fails_regression_from_641()
+ {
+ var p1 = new Person { ChildId = Guid.NewGuid()};
+ var p2 = new Person { ChildId = Guid.NewGuid()};
+ theSession.Store(p1,p2);
+ await theSession.SaveChangesAsync();
+ Guid[] ids = [p1.ChildId.Value];
+ var results = await theSession.Query()
+ .Where(x => x.ChildId!.Value.In(ids))
+ .ToListAsync();
+ results.Single().ChildId.ShouldBe(p1.ChildId);
+ }
+
+ [Fact]
+ public async Task Bug_3150_query_multiple_times()
+ {
+ // if you call BeginTransactionAsync then the issue goes away..
+ //await theSession.BeginTransactionAsync(CancellationToken.None);
+
+ async Task DoQuery()
+ {
+ var children = new Dictionary();
+ await theSession.Query()
+ .Include(x => x.ChildId!, children)
+ .ToListAsync();
+ }
+
+ theSession.Logger = new TestOutputMartenLogger(_output);
+
+ await DoQuery();
+
+ // second invocation throws MartenCommandException "42P01: relation "mt_temp_id_list1" does not exist"
+ await DoQuery();
+ }
+}
+
+public class Person
+{
+ public Guid Id { get; set; }
+
+ [DuplicateField]
+ public Guid? ChildId { get; set; }
+}
+
+public class Person3150
+{
+ public Guid Id { get; set; }
+
+ [DuplicateField]
+ public string? Name { get; set; }
+ public Guid? ChildId { get; set; }
+}
diff --git a/src/Marten/Internal/Storage/DocumentStorage.cs b/src/Marten/Internal/Storage/DocumentStorage.cs
index 97f0258d4b..ad74146983 100644
--- a/src/Marten/Internal/Storage/DocumentStorage.cs
+++ b/src/Marten/Internal/Storage/DocumentStorage.cs
@@ -46,6 +46,7 @@ public abstract class DocumentStorage: IDocumentStorage, IHaveMe
private readonly string[] _selectFields;
private ISqlFragment? _defaultWhere;
protected Action _setter;
+ private readonly DocumentMapping _document;
public DocumentStorage(StorageStyle storageStyle, DocumentMapping document)
{
@@ -65,20 +66,7 @@ public DocumentStorage(StorageStyle storageStyle, DocumentMapping document)
var fieldSelector = _selectFields.Join(", ");
_selectClause = $"select {fieldSelector} from {document.TableName.QualifiedName} as d";
-
- if (DuplicatedFields.Any())
- {
- var duplicatedFields = DuplicatedFields.Select(x => "d." + x.ColumnName).Where(x => !_selectFields.Contains(x));
- var allFields = _selectFields.Concat(duplicatedFields).ToArray();
- SelectClauseWithDuplicatedFields = new DuplicatedFieldSelectClause(TableName.QualifiedName, $"select {allFields.Join(", ")} from {document.TableName.QualifiedName} as d",
- allFields, typeof(T), this);
- }
- else
- {
- SelectClauseWithDuplicatedFields = this;
- }
-
-
+ _document = document;
_loaderSql =
$"select {fieldSelector} from {document.TableName.QualifiedName} as d where id = $1";
@@ -107,7 +95,26 @@ public DocumentStorage(StorageStyle storageStyle, DocumentMapping document)
public bool UseNumericRevisions { get; }
- public ISelectClause SelectClauseWithDuplicatedFields { get; }
+ // TODO -- convert to a method in V8
+ // this has to be a new instance every time because of how it gets the FromObject
+ // renamed in Include() batches
+ public ISelectClause SelectClauseWithDuplicatedFields
+ {
+ get
+ {
+ if (DuplicatedFields.Any())
+ {
+ var duplicatedFields = DuplicatedFields.Select(x => "d." + x.ColumnName).Where(x => !_selectFields.Contains(x));
+ var allFields = _selectFields.Concat(duplicatedFields).ToArray();
+ return new DuplicatedFieldSelectClause(TableName.QualifiedName, $"select {allFields.Join(", ")} from {_document.TableName.QualifiedName} as d",
+ allFields, typeof(T), this);
+ }
+ else
+ {
+ return this;
+ }
+ }
+ }
MetadataColumn[] IHaveMetadataColumns.MetadataColumns()
{
diff --git a/src/Marten/Linq/Members/DuplicatedField.cs b/src/Marten/Linq/Members/DuplicatedField.cs
index 65df128a43..867c25cbac 100644
--- a/src/Marten/Linq/Members/DuplicatedField.cs
+++ b/src/Marten/Linq/Members/DuplicatedField.cs
@@ -216,6 +216,8 @@ public virtual TableColumn ToColumn()
public IQueryableMember FindMember(MemberInfo member)
{
+ if (member.Name == "Value") return this;
+
// Only really using this for string ToLower() and ToUpper()
if (MemberType == typeof(string))
{