Skip to content
This repository has been archived by the owner on Jun 16, 2024. It is now read-only.

Linked Entity Query with a mixture of null and not null values returns wrong value #324

Closed
daveb84 opened this issue Jul 5, 2018 · 1 comment
Assignees
Labels
Milestone

Comments

@daveb84
Copy link

daveb84 commented Jul 5, 2018

I have a query that returns columns from a linked entity. When the value of one of the fields of the linked entity is null, it being returned as the value of the previous entity when it should be being returned as null.

e.g.
I have forked the repo and added a unit test - see this commit:
daveb84@b17605d

Full test code:

[Fact]
public void TestRetriveMultipleWithLinkEntityWithAlternateNullField()
{
    // ARRANGE

    List<Entity> initialEntities = new List<Entity>();

    Entity parentEntity = new Entity("parent");
    parentEntity["parentname"] = "parent name";
    parentEntity.Id = Guid.NewGuid();
    initialEntities.Add(parentEntity);

    // create the first child which has the "myvalue" field set to "value"
    Entity childEntity1 = new Entity("child");
    childEntity1["parent"] = parentEntity.ToEntityReference();
    childEntity1["name"] = "entity1";
    childEntity1["myvalue"] = "value";
    childEntity1.Id = Guid.NewGuid();
    initialEntities.Add(childEntity1);

    // create the second child which has the "myvalue" field set to null
    Entity childEntity2 = new Entity("child");
    childEntity2["parent"] = parentEntity.ToEntityReference();
    childEntity2["name"] = "entity2";
    childEntity2["myvalue"] = null;
    childEntity2.Id = Guid.NewGuid();
    initialEntities.Add(childEntity2);

    XrmFakedContext context = new XrmFakedContext();
    IOrganizationService service = context.GetOrganizationService();

    context.Initialize(initialEntities);

    // the query selects the "parent" entity, and joins to the "child" entities
    QueryExpression query = new QueryExpression("parent");
    query.ColumnSet = new ColumnSet("parentname");

    LinkEntity link = new LinkEntity("parent", "child", "parentid", "parent", JoinOperator.Inner);
    link.EntityAlias = "c";
    link.Columns = new ColumnSet("name", "myvalue");

    query.LinkEntities.Add(link);

    // ACT

    DataCollection<Entity> results = service.RetrieveMultiple(query).Entities;

    // ASSERT

    // fields for the first entity work as expected...
    string entity1Name = results[0].GetAttributeValue<AliasedValue>("c.name").Value as string;
    string entity1Value = results[0].GetAttributeValue<AliasedValue>("c.myvalue").Value as string;
        
    Assert.Equal("entity1", entity1Name);
    Assert.Equal("value", entity1Value);

    // fields for the second entity do not.  
    // The child "name" field is correct, but the "myvalue" field is returning the value of the previous
    // entity when it should be returning null
    string entity2Name = results[1].GetAttributeValue<AliasedValue>("c.name").Value as string;
    string entity2Value = results[1].GetAttributeValue<AliasedValue>("c.myvalue").Value as string;

    // this works fine:
    Assert.Equal("entity2", entity2Name);

    // this fails (entity2Value is "value")
    Assert.Equal(null, entity2Value);
}
@JanFelixReuter
Copy link

We have stumbled upon the same issue. Here is another test to reproduce it:

[TestMethod]
public void Attributes_Dont_Bleed_Into_Other_Records_When_Joining()
{
    var organizationService = new FakeXrmEasy.XrmFakedContext().GetOrganizationService();

    var mainId = organizationService.Create(new Entity("main"));

    //NOTE: The order of creation of the linked entities is important.
    //Linked entity with attribute set to a value
    organizationService.Create(new Entity("linked")
    {
        Attributes = new AttributeCollection {{"mainid", mainId}, {"attribute", "Data"}}
    });

    //Linked entity with attribute set to null
    organizationService.Create(new Entity("linked")
    {
        Attributes = new AttributeCollection {{"mainid", mainId}, {"attribute", null}}
    });

    //Linked entity with attribute not set at all
    organizationService.Create(new Entity("linked")
    {
        Attributes = new AttributeCollection { { "mainid", mainId } }
    });

    var queryExpression = new QueryExpression("main")
    {
        ColumnSet = new ColumnSet(true),
        LinkEntities =
        {
            new LinkEntity("main", "linked", "mainid", "mainid", JoinOperator.Inner)
            {
                EntityAlias = "linked",
                Columns = new ColumnSet(true)
            }
        }
    };

    //Should return all three linked records
    var result = organizationService.RetrieveMultiple(queryExpression);

    //Get attribute values of all linked entities
    var attributeValues = result.Entities
            .Select(e => e.Attributes.TryGetValue("linked.attribute", out var value) ? (value as AliasedValue)?.Value : null)
            .ToList(); 

    //Should get 1x Data and 2x null
    attributeValues.Should().BeEquivalentTo(new object[] {"Data", null, null});
    //Actual values: "Data", "Data", "Data"
}

The problem appears to be in the method JoinAttributes. The "main" e entity gets re-used for every linked entity. Attributes from previous linked entities are not overwritten when they are null.

@jordimontana82 jordimontana82 added this to the v1.47.1 milestone Sep 5, 2018
@jordimontana82 jordimontana82 self-assigned this Sep 5, 2018
BetimBeja added a commit to BetimBeja/fake-xrm-easy-v1 that referenced this issue Nov 4, 2018
note. fixed an error on the proposed test case too.
@BetimBeja BetimBeja mentioned this issue Nov 4, 2018
mtone pushed a commit to mtone/fake-xrm-easy that referenced this issue Jun 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants