Skip to content

Problems adding Entities / Related Entities  #759

@slnetgit

Description

@slnetgit

Short summary (3-5 sentences) describing the issue.
Adding new Entity with Savechengesoption.Batch) with related Entit(ies) from Dataservicecollection does not work as expected

Assemblies affected

For Information:
Project references server:

TargetFramework>net8.0 UserSecretsId>0747c9f0-3a8d-4969-a360-a7dc2e7f8489 PlatformTarget>x64

"IBM.EntityFrameworkCore" Version="8.0.0.200" />
"Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.16" />
"Microsoft.AspNetCore.DataProtection" Version="7.0.2" />
"Microsoft.EntityFrameworkCore.Design" Version="8.0.5">

"Microsoft.Extensions.Configuration" Version="7.0.0" />
"Microsoft.OData.ModelBuilder" Version="1.0.9" />
"Microsoft.Restier.AspNetCore" Version="1.1.0" />
"Microsoft.Restier.Core" Version="1.1.0" />
"Microsoft.Restier.EntityFrameworkCore" Version="1.1.0" />
"Newtonsoft.Json" Version="13.0.3" />
Swashbuckle.AspNetCore" Version="6.5.0" />

Reproduce steps

I want to add new Element with related elements.
relation is 1:n

car key is nr
box key is car_nr, nr

the described issue is on

DataServiceCollection cars = new DataServiceCollection(context);
car newcar = new car() { nr = "test1", such = "test1",name="Test",kennzeichen="hallo" };

newcar.boxes.Add(new box() {car_nr="test1", nr = 1, dompos = 1,art_nr=""});

cars.Add(newcar);

context.SaveChanges(SaveChangesOptions.BatchWithSingleChangeset); // causes exception

Expected result

In WCF Odata V3 with Savechanges(Batch) this works as expected. New car is created with boxes. No need to enter car_id in every box created

When I use restier 1 or 1.1 i have to use
context.SaveChanges(); // works but causes single requests and neds car_id in box . No transaction around request.

Actual result

when I use cont.SaveChanges(SaveChangesOptions.BatchWithSingleChangeset)
this results in a strange Error message
Stacktrace:
Microsoft.OData.Core.dll!Microsoft.OData.UriParser.ODataPathParser.CreateDynamicPathSegment(Microsoft.OData.UriParser.ODataPathSegment previous, string identifier, string parenthesisExpression) Unbekannt
Microsoft.OData.Core.dll!Microsoft.OData.UriParser.ODataPathParser.CreateFirstSegment(string segmentText) Unbekannt
Microsoft.OData.Core.dll!Microsoft.OData.UriParser.ODataPathParser.ParsePath(System.Collections.Generic.ICollection segments) Unbekannt
Microsoft.OData.Core.dll!Microsoft.OData.UriParser.ODataPathFactory.BindPath(System.Collections.Generic.ICollection segments, Microsoft.OData.UriParser.ODataUriParserConfiguration configuration) Unbekannt
Microsoft.OData.Core.dll!Microsoft.OData.UriParser.ODataUriParser.ParsePathImplementation() Unbekannt
Microsoft.OData.Core.dll!Microsoft.OData.UriParser.ODataUriParser.Initialize() Unbekannt
Microsoft.OData.Core.dll!Microsoft.OData.UriParser.ODataUriParser.ParsePath() Unbekannt
Microsoft.AspNetCore.OData.dll!Microsoft.AspNet.OData.Routing.DefaultODataPathHandler.Parse(string serviceRoot, string odataPath, System.IServiceProvider requestContainer, bool template) Unbekannt
Microsoft.AspNetCore.OData.dll!Microsoft.AspNet.OData.Routing.DefaultODataPathHandler.Parse(string serviceRoot, string odataPath, System.IServiceProvider requestContainer) Unbekannt
Microsoft.AspNetCore.OData.dll!Microsoft.AspNet.OData.Routing.ODataPathRouteConstraint.GetODataPath(string oDataPathString, string uriPathString, string queryString, System.Func<System.IServiceProvider> requestContainerFactory) Unbekannt
Microsoft.AspNetCore.OData.dll!Microsoft.AspNet.OData.Routing.ODataPathRouteConstraint.Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) Unbekannt
Microsoft.AspNetCore.Routing.dll!Microsoft.AspNetCore.Routing.RouteConstraintMatcher.Match(System.Collections.Generic.IDictionary<string, Microsoft.AspNetCore.Routing.IRouteConstraint> constraints, Microsoft.AspNetCore.Routing.RouteValueDictionary routeValues, Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, Microsoft.AspNetCore.Routing.RouteDirection routeDirection, Microsoft.Extensions.Logging.ILogger logger) Unbekannt
Microsoft.AspNetCore.Routing.dll!Microsoft.AspNetCore.Routing.RouteBase.RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context) Unbekannt
Microsoft.AspNetCore.Routing.dll!Microsoft.AspNetCore.Routing.RouteCollection.RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context) Unbekannt
Microsoft.AspNetCore.Routing.dll!Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext httpContext) Unbekannt

Microsoft.Restier.AspNetCore.dll!Microsoft.Restier.AspNetCore.Middleware.ODataBatchHttpContextFixerMiddleware.InvokeAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Http.IHttpContextAccessor contextAccessor) Zeile 21 C#
Microsoft.AspNetCore.OData.dll!Microsoft.AspNet.OData.Batch.ODataBatchRequestItem.SendRequestAsync(Microsoft.AspNetCore.Http.RequestDelegate handler, Microsoft.AspNetCore.Http.HttpContext context, System.Collections.Generic.IDictionary<string, string> contentIdToLocationMapping) Unbekannt
Microsoft.Restier.AspNetCore.dll!Microsoft.Restier.AspNetCore.Batch.RestierBatchChangeSetRequestItem.SendRequestAsync(Microsoft.AspNetCore.Http.RequestDelegate handler) Zeile 38 C#
Microsoft.AspNetCore.OData.dll!Microsoft.AspNet.OData.Batch.DefaultODataBatchHandler.ExecuteRequestMessagesAsync(System.Collections.Generic.IEnumerable<Microsoft.AspNet.OData.Batch.ODataBatchRequestItem> requests, Microsoft.AspNetCore.Http.RequestDelegate handler) Unbekannt
Microsoft.AspNetCore.OData.dll!Microsoft.AspNet.OData.Batch.DefaultODataBatchHandler.ProcessBatchAsync(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.RequestDelegate nextHandler) Unbekannt

in OdataUtriParser the Uri which has to be pasrsed is :http://192.168.0.87:5000/$121/boxes
I think when handling the call as a Batch the batch should be splitted in the single operations but somehow this gets lost during the call.
Do yo have a hint ?

in OdataPathParser this stops with
private void CreateDynamicPathSegment(ODataPathSegment previous, string identifier, string parenthesisExpression)
{
if (configuration.ParseDynamicPathSegmentFunc != null)
{
ICollection collection = configuration.ParseDynamicPathSegmentFunc(previous, identifier, parenthesisExpression);
parsedSegments.AddRange(collection);
return;
}
if (previous == null)
{
>>>>>> here throw ExceptionUtil.CreateResourceNotFoundError(identifier); >>> identifier is $121
}

Expected Behavior : Correct Insert in Batch with single changeset
For using this as a successor to wcf odata it is essential for me to be able to update Contexts with savechanges Batch handling in a Transaction.

Additional details

Aditionally

  1. Problem when related entity does not have id of master Entity
    In the box Entities I have to add the kfz nr, otherwise the insert will not happen. Neither with context.Savechanges() nor with
    context.SaveChanges(SaveChangesOptions.BatchWithSingleChangeset)

If I enter Null as Kfz Nr I get an Exception that the column does not allow null values,
If I Enter an Empty string, Just a new Item with Empty kfz_nr is created.

Expected Bahavior: Savechanges should work like in Wcf Odata V3 with no need to add number of Master Entity in the related entity .

  1. Next problem with entity references
    When the entity box contains an object reference to the car entity this causes an exception that the payload should not contain navigation properties

Expected behavior: References within the object structure should not cause problems in updating object graphs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions