Entity Framework Entity Saving
hi guys can someone help me with EF?
I have a Visitor and want to add a plannedVisit to it
public sealed class Visitor : Entity<Guid>
{
public ICollection<PlannedVisit> PlannedVisits { get; set; } = new List<PlannedVisit>();
}
public sealed class PlannedVisit : Entity<Guid>
{
public Guid VisitorId { get; set; }
public Visitor Visitor { get; set; }
}
Configuration
builder.HasMany(visitor => visitor.PlannedVisits)
.WithOne(plannedVisit => plannedVisit.Visitor)
.HasForeignKey(plannedVisit => plannedVisit.VisitorId);
Can i somehow add the plannedVisit without calling _context.PlannedVisits.Add(plannedVisit) to the Changetracker / will the changetracker somehow pick it up?
Would be nice if i could just do it like this, but here i alwais get an error
public Result<PlannedVisit> PlanVisit(DateTime plannedArrival, DateTime? plannedDeparture, VisitLocation location, List<BriefingType> requiredBriefings, VisitGroup group)
{
var result = PlannedVisit.Create(
this,
plannedArrival,
plannedDeparture,
location,
group,
requiredBriefings);
if (result.Failed)
{
return result.Error;
}
PlannedVisits.Add(result.Value);
return result.Value;
}
15 Replies
"an error" isn't very helpful, in general if you add entities to a navigation property EF will detect the changes and do what is needed to get it in the database
Mb
Error
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: "The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See https://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions."
Handling Concurrency Conflicts - EF Core
Managing conflicts when the same data is updated concurrently with Entity Framework Core
that looks like you're moving entity instances between dbcontexts
hmm should not be possible i do have mutiple dbcontext for different dbs but the visitor as well as the PlannedVisit are in the same Db and same DbContext
but are you creating a new dbcontext between loading the entity and trying to save changes?
nope alwais the same scoped Dbcontext
internal sealed class PlanVisitCommandHandler : ICommandHandler<PlanVisitCommand, PlannedVisitDto>
{
private readonly IVisitorDbContext _context;
public PlanVisitCommandHandler(IVisitorDbContext context)
{
_context = context;
}
public async Task<Result<PlannedVisitDto>> Handle(PlanVisitCommand request, CancellationToken cancellationToken)
{
Visitor? visitor = await _context.Visitors.FirstOrDefaultAsync(visitor => visitor.Id == request.VisitorId, cancellationToken);
if (visitor is null)
{
return VisitorErrors.VisitorNotFound;
}
var result = visitor.PlanVisit(
request.PlannedArrival,
request.PlannedDeparture,
request.Location,
request.RequiredBriefings.ToList());
if (result.Failed)
{
return result.Error;
}
await _context.SaveChangesAsync(cancellationToken);
return PlannedVisitDto.From(result.Value);
}
}
services.AddDbContext<IVisitorDbContext, VisitorDbContext>((services, options) =>
{
DatabaseSettings databaseSettings = services.GetRequiredService<IOptions<DatabaseSettings>>().Value;
options.UseSqlServer(databaseSettings.VisitorModuleConnectionString,
e => e.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name));
options.AddInterceptors(services.GetServices<ISaveChangesInterceptor>());
});
.
.
Cant seem to figure it out why i get this error
look at the generated SQL and see what it's trying to do
I don't suppose
visitor.PlanVisit
does any db work?Well its a navigation property
Seems like EF Core tries to update the entity instead of inserting it?
UPDATE [visitor].[PlannedVisits] SET [Location] = @p0, [PlannedArrival] = @p1, [PlannedDeparture] = @p2, [RequiredBriefings] = @p3, [State] = @p4, [VisitId] = @p5, [VisitorId] = @p6, [GroupHeadCount] = @p7, [Group_Names] = @p8
OUTPUT 1
WHERE [Id] = @p9;
How is
visitor.PlanVisit
a navigation property, if you call it like a method?ups my bad
wrong
i cant read
Planvisit does not do any db work
just creates the plannedVisit and adds it to the NavigationProperty "PlannedVisits"
public Result<PlannedVisit> PlanVisit(DateTime plannedArrival, DateTime? plannedDeparture, VisitLocation location, List<BriefingType> requiredBriefings, VisitGroup group)
{
var result = PlannedVisit.Create(
this,
plannedArrival,
plannedDeparture,
location,
group,
requiredBriefings);
if (result.Failed)
{
return result.Error;
}
PlannedVisits.Add(result.Value);
return result.Value;
}
Is maybe anything wrong with doing this? (setting it to new list?)
public sealed class Visitor : Entity<Guid>
{
public ICollection<PlannedVisit> PlannedVisits { get; set; } = new List<PlannedVisit>();
}
btw how to make code be better readable instead of just text?
in discord
$codegif
thx
np