Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion evergreen/evergreen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,22 @@ functions:
BUILD_CONFIGURATION="Debug EF10" \
./evergreen/run-tests.sh

run-tests-macos:
- command: shell.exec
type: test
params:
working_dir: mongo-efcore-provider
script: |
${PREPARE_SHELL}
DRIVER_VERSION=${DRIVER_VERSION} \
OS=${OS} \
MONGODB_URI="${MONGODB_URI}" \
ATLAS_URI="${ATLAS_URI}" \
MONGODB_VERSION="${version}" \
CRYPT_SHARED_LIB_PATH=${CRYPT_SHARED_LIB_PATH} \
BUILD_CONFIGURATION="Debug EF10" \
./evergreen/run-tests.sh

cleanup:
- command: shell.exec
params:
Expand Down Expand Up @@ -431,6 +447,11 @@ tasks:
- func: bootstrap-mongo-orchestration
- func: run-tests

- name: main-tests-macos
commands:
- func: bootstrap-mongo-orchestration
- func: run-tests-macos

- name: pack-packages
commands:
- func: pack-packages
Expand Down Expand Up @@ -566,14 +587,25 @@ buildvariants:
- matrix_name: main-tests
matrix_spec:
version: ["5.0", "6.0", "7.0", "latest"]
os: "*"
os: ["windows-64", "ubuntu-2004"]
driver: "*"
topology: "replicaset"
display_name: "${driver} Driver on ${os} with ${version} ${topology} Server"
tags: ["tests-variant"]
tasks:
- name: main-tests

- matrix_name: main-tests-macos
matrix_spec:
version: ["5.0", "6.0", "7.0", "latest"]
os: "macos-14"
driver: "*"
topology: "replicaset"
display_name: "${driver} Driver on ${os} with ${version} ${topology} Server"
tags: ["tests-variant"]
tasks:
- name: main-tests-macos

- matrix_name: validate-apidocs
matrix_spec:
os: "ubuntu-2004"
Expand Down
39 changes: 37 additions & 2 deletions src/MongoDB.EntityFrameworkCore/Storage/MongoDatabaseWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ public MongoDatabaseWrapper(
public override int SaveChanges(IList<IUpdateEntry> entries)
{
var rootEntries = GetAllChangedRootEntries(entries);
var updates = MongoUpdate.CreateAll(rootEntries);
var updates = MongoUpdate.CreateAll(rootEntries).ToList();
AddEntriesPromotedDuringSave(entries);

// Explicit transaction mode
if (_transactionManager.CurrentTransaction is MongoTransaction mongoTransaction)
Expand Down Expand Up @@ -121,7 +122,8 @@ public override int SaveChanges(IList<IUpdateEntry> entries)
public override async Task<int> SaveChangesAsync(IList<IUpdateEntry> entries, CancellationToken cancellationToken = default)
{
var rootEntries = GetAllChangedRootEntries(entries);
var updates = MongoUpdate.CreateAll(rootEntries);
var updates = MongoUpdate.CreateAll(rootEntries).ToList();
AddEntriesPromotedDuringSave(entries);

// Explicit transaction mode
if (_transactionManager.CurrentTransaction is MongoTransaction mongoTransaction)
Expand Down Expand Up @@ -260,6 +262,7 @@ private bool ShouldUseImplicitTransaction(int operationCount)
private static HashSet<IUpdateEntry> GetAllChangedRootEntries(IList<IUpdateEntry> entries)
{
var changedRootEntries = new HashSet<IUpdateEntry>(entries);
List<IUpdateEntry>? promotedRoots = null;
foreach (var entry in entries)
{
if (!entry.EntityType.IsDocumentRoot())
Expand All @@ -268,16 +271,48 @@ private static HashSet<IUpdateEntry> GetAllChangedRootEntries(IList<IUpdateEntry
if (root.EntityState == EntityState.Unchanged)
{
root.EntityState = EntityState.Modified;
(promotedRoots ??= []).Add(root);
}

changedRootEntries.Remove(entry);
changedRootEntries.Add(root);
}
}

// Add roots we promoted to Modified into the entries list so that
// EF Core's AcceptAllChanges will reset them to Unchanged after save.
if (promotedRoots != null)
{
foreach (var root in promotedRoots)
{
entries.Add(root);
}
}

return changedRootEntries;
}

/// <summary>
/// Adds any entries that were promoted to Modified during save preparation
/// (root entity promotion and FK cascade from ordinal key reassignment)
/// into the entries list so EF Core's AcceptAllChanges will reset them after save.
/// </summary>
private static void AddEntriesPromotedDuringSave(IList<IUpdateEntry> entries)
{
if (entries.Count == 0) return;

var existingEntries = new HashSet<IUpdateEntry>(entries);
var stateManager = ((InternalEntityEntry)entries[0]).StateManager;

foreach (var entry in stateManager.GetEntriesForState(modified: true))
{
if (!existingEntries.Contains(entry) && !entry.EntityType.IsDocumentRoot())
{
entries.Add(entry);
}
}
}

private static IUpdateEntry GetRootEntry(InternalEntityEntry entry)
{
while (true)
Expand Down
2 changes: 1 addition & 1 deletion src/MongoDB.EntityFrameworkCore/Storage/MongoUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ private static void WriteOwnedEntities(IBsonWriter writer, IUpdateEntry entry)
var ordinalKeyProperty = FindOrdinalKeyProperty(embeddedEntry.EntityType);
if (ordinalKeyProperty != null && embeddedEntry.HasTemporaryValue(ordinalKeyProperty))
{
embeddedEntry.SetStoreGeneratedValue(ordinalKeyProperty, ordinal);
embeddedEntry.SetStoreGeneratedValue(ordinalKeyProperty, ordinal, setModified: false);
}

WriteEntity(writer, embeddedEntry, _ => true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace MongoDB.EntityFrameworkCore.FunctionalTests.Design
public partial class SimpleContextModel
{
private SimpleContextModel()
: base(skipDetectChanges: false, modelId: new Guid("436c97bc-761b-453c-a4f6-30ed2976f3ea"), entityTypeCount: 2)
: base(skipDetectChanges: false, modelId: new Guid("13956f7e-4a9d-432b-aa8f-478d1f251dfc"), entityTypeCount: 2)
{
}

Expand Down
Loading