Developer forum

Forum » Development » MappingConditionals ignored in Data Integration job

MappingConditionals ignored in Data Integration job

Umar Farooq
Reply

HI,

I have created a Data Integration job using an EcomProvider as the source and an XML provider as the destination. A condition on ProductId works as expected when configured directly in the job. However, when I attempt to apply or modify this condition programmatically via a custom scheduled task add-in, the job ignores the condition and exports all products.

In my implementation, I load the job for each product ID, update or create a conditional group on the mappings, then save and run the job. Although the conditionals are set correctly in code, they are not respected during execution. I would appreciate any clarification on this should be handled. below is the code I have so far

foreach (var ProductId in productIds)
{
    Job? jobToRun = Job.GetJob($"ExportProductData{Path.DirectorySeparatorChar}ProductDataExport");
    if(jobToRun == null)
    {
        Logger.Current.Error($"Could not find job at path: {jobXmlPath}");
        return false;
    }
    foreach (var mapping in jobToRun.Mappings)
    {
        var existingGroup = mapping.ConditionalGroups.FirstOrDefault();
        var column = new Column("ProductId", typeof(string), mapping.SourceTable);
        var mappingConditional = new MappingConditional(jobToRun.Source, column, ConditionalOperator.EqualTo, ProductId, 1, mapping, false) { SourceColumnName = "ProductId" };
        if (existingGroup != null)
        {
            foreach (var existingConditional in existingGroup.Conditionals)
            {
                existingGroup.RemoveConditional(existingConditional);
            }
 
            existingGroup.AddConditional(mappingConditional);
        }
        else {
            var mappingConditionalGroup = mapping.AddConditionalGroup(ConditionalGroupOperator.And);
            mappingConditionalGroup.AddConditional(mappingConditional);
        }
    }
 
    jobToRun.Save();
bool success = jobToRun.Run();
}

PS: this is implemented on DW10

Replies

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

What’s happening here in DW10 is:

Your condition is being added to the group, but the runtime filter is not built from mapping.ConditionalGroups. It’s built from mapping.Conditionals.

In DW10, the Ecom source reader generates the SQL filter using mapping.Conditionals, and the grouping logic comes from the Group property on those conditionals.

The key detail is:

  • AddConditionalGroup() → only creates the group
  • MappingConditionalGroup.AddConditional(...) → only adds the conditional to the group
  • It does NOT:
    • add the conditional to mapping.Conditionals
    • set conditional.Group automatically for manually created conditionals

So your condition never makes it into the actual runtime filter.

Fix

You need to keep both collections in sync:

 
foreach (var productId in productIds)
{
Job? jobToRun = Job.GetJob($"ExportProductData{Path.DirectorySeparatorChar}ProductDataExport");
if (jobToRun is null)
{
return false;
}

foreach (var mapping in jobToRun.Mappings)
{
var group = mapping.ConditionalGroups.FirstOrDefault()
?? mapping.AddConditionalGroup(ConditionalGroupOperator.And);

foreach (var existing in group.Conditionals.ToList())
{
group.RemoveConditional(existing);
mapping.Conditionals.Remove(existing);
}

var sourceColumn = mapping.SourceTable?.Columns
.FirstOrDefault(c => string.Equals(c.Name, "ProductId", StringComparison.OrdinalIgnoreCase))
?? new Column("ProductId", typeof(string), mapping.SourceTable);

var conditional = group.AddConditional(sourceColumn, ConditionalOperator.EqualTo, productId, false);

// Important: keep things in sync
conditional.Group = group;
conditional.SourceColumnName = "ProductId";
mapping.Conditionals.Add(conditional);
}

jobToRun.Save();
jobToRun.Run();
}
 

Alternative (recommended)

If your goal is just to apply a runtime ProductId filter, you don’t need to manipulate conditional groups at all.

DW10 already supports parameterized filters via the provider pipeline (e.g. ReplaceMappingConditionalsWithValuesFromRequest(...) and the filter parameter handling).

That approach is cleaner and avoids manually syncing groups and conditionals.

 
Umar Farooq
Reply

Hi Nicolai,

Keeping Both in conditions in sync did the trick.

Could you elaborate a bit on how you’d actually wire this up using the provider pipeline? Specifically, how would you pass the ProductId on the run time. I tried something like
parameterized.Parameters["filter"= $"ProductId = '{productId}'"; but it didn't worked

If you have a example or a recommended starting point (e.g. where in the pipeline this should be configured), that would really help.

 

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

Yes, that is possible through the provider pipeline, but the important detail is that the filter parameter is not SQL syntax.

This will not work:

parameterized.Parameters["filter"] = $"ProductId = '{productId}'";

because Dynamicweb expects the filter in this format:

{ColumnName|Operator|Value}

So for ProductId, the runtime filter should be passed like this:

var job = Job.GetJob($"ExportProductData{Path.DirectorySeparatorChar}ProductDataExport"); if (job?.Source is IParameterizedDestination parameterized) { parameterized.Parameters["filter"] = $"{{ProductId|=|{productId}}}"; } job?.Run();

A few notes:

  • The parameter is read from job.Source
  • The filter format is parsed into mapping conditionals internally before the provider runs
  • Supported operators are things like =, <, >, <=, >=, <>, LIKE, IN, NOTLIKE, etc.

You can also pass multiple filters like this:

parameterized.Parameters["filter"] = "{ProductId|=|10001;ProductLanguageId|=|LANG1}";

So the recommended starting point is simply:

  1. Load the job
  2. Set job.Source.Parameters["filter"]
  3. Call job.Run()

In other words, if you only need to pass a ProductId at runtime, this is a cleaner approach than manually modifying ConditionalGroups.

Regards,
Nicolai

 

You must be logged in to post in the forum