BulkMerge - Many to Many relationships
Description
I'm trying to merge a many to many relationship using the graph feature. The Ids are generated out of the database, so I have to key off the Sku for Product and the Name for Manufacturer.
{
"Products": [
{
"Sku": 111222,
"Manufacturer": {
"Name": "Foo",
"Description": "Bar"
}
]
}
Table Structure:
Product
Id
Sku
ProductMaufacturer
ProductId
ManufacturerId
Manufacturer
Id
Name
Description
I'm trying to do something like this:
context.BulkMerge(parentProducts, options =>
{
options.IncludeGraph = true;
options.ColumnInputExpression = product => new {
product.Sku,
};
options.ColumnPrimaryKeyExpression = product => new
{
product.Sku,
};
options.IncludeGraphOperationBuilder = operation =>
{
if (operation is BulkOperation<ProductManufacturer> bulkProductManufacturer)
{
bulkProductManufacturer.ColumnPrimaryKeyExpression = x => new
{
x.Product.Sku,
x.Manufacturer.Name,
};
}
else if (operation is BulkOperation<Manufacturer> bulkManufacturer)
{
bulkManufacturer.ColumnPrimaryKeyExpression = manufacturer => new
{
manufacturer.Name,
};
}
};
});
What am I missing? The graph examples don't specify everything outlined in the exception.
Exception
Exception message:
Stack trace:
System.Exception: 'When using `IncludeGraph`, some options must be set in the `IncludeGraphBuilder` (See: https://entityframework-extensions.net/include-graph). The following options must be specified in `IncludeGraphBuilder`: ColumnInputExpression, ColumnPrimaryKeyExpression, IgnoreOnMergeUpdateExpression, LambdaIgnoreOnMergeUpdateExpression, LambdaInputExpression, LambdaPrimaryKeyExpression'
Fiddle or Project (Optional)
If you are able,
Provide a Fiddle that reproduces the issue: https://dotnetfiddle.net/Uqe9sf
Or provide a project/solution that we can run to reproduce the issue.
- Make sure the project compile
- Make sure to provide only the code that is required to reproduce the issue, not the whole project
- You can send private code here: [email protected]
Otherwise, make sure to include as much information as possible to help our team to reproduce the issue.
Note: More information you provide, faster we can implement a solution.
Further technical details
- EF version: 3.0.0
- EF Extensions version: 3.0.9
- Database Provider: Sql Server
Hello @mr-eric-walter ,
The IncludeGraph is not very obvious. Everything that depend on an entity must be specified in the IncludeGraphOperationBuilder.
For example, the BatchSize can be specifed outside but ColumnInputExpression must be specified inside since it depends on an entity type.
So you probably need to do something like this:
context.BulkMerge(parentProducts, options =>
{
options.IncludeGraph = true;
options.IncludeGraphOperationBuilder = operation =>
{
if (operation is BulkOperation<ProductManufacturer> bulkProductManufacturer)
{
bulkProductManufacturer.ColumnPrimaryKeyExpression = x => new
{
x.Product.Sku,
x.Manufacturer.Name,
};
}
else if (operation is BulkOperation<Manufacturer> bulkManufacturer)
{
bulkManufacturer.ColumnPrimaryKeyExpression = manufacturer => new
{
manufacturer.Name,
};
}
else if (operation is BulkOperation<Product> bulkProduct)
{
bulkProduct.ColumnInputExpression = product => new {
product.Sku,
};
bulkProduct.ColumnPrimaryKeyExpression = product => new
{
product.Sku,
};
}
};
});
Let me know if you successfully make it work.
Best Regards,
Jonathan
Thank you so much. That helped me get past that issue. Now I'm seeing this issue. Since I do not have IDs for those entities yet, will I not be able to map to the unique value for that entity?
System.InvalidOperationException: 'The property 'ProductId' on entity type 'ProductManufacturer'
has a temporary value. Either set a permanent value explicitly or ensure that the
database is configured to generate values for this property.
Hello @mr-eric-walter ,
You will find a working example in the attachment. We used the same entity but with probably some small difference.
On our side, we have found something strange. It looks the ProductId is not returned by default when there is a ColumnInputExpression and ColumnPrimaryKeyExpression set.
So perhaps adding the following line will make your project work:
bulkProduct.ColumnOutputExpression = product => product.ProductID;
We will investigate it on our side why that's happening. But meanwhile, could you try it and let us know if you successfully make it work?
Here is the project we made: EF_ManyToMany.zip
Hello @mr-eric-walter
Since our last conversation, we haven't heard from you.
Did you get the chance to try the example?
Looking forward to hearing from you,
Jon