Linq query returning erroneous record from FakeXrmEasy context

204 views Asked by At

I'm new to the world of FakeXrmEasy and trying to implement some unit tests in large existing code base written by another team :)

I have an entity set in OnPremise DynamicsCRM app where the entity has the following properties:

[Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("statuscode")]
public Microsoft.Xrm.Sdk.OptionSetValue statuscode
{
    get
    {
        return this.GetAttributeValue<Microsoft.Xrm.Sdk.OptionSetValue>("statuscode");
    }
    set
    {
        this.OnPropertyChanging("statuscode");
        this.SetAttributeValue("statuscode", value);
        this.OnPropertyChanged("statuscode");
    }
}

/// <summary>
/// Invoice
/// </summary>
[Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("invoiceid")]
public Microsoft.Xrm.Sdk.EntityReference InvoiceId
{
    get
    {
        return this.GetAttributeValue<Microsoft.Xrm.Sdk.EntityReference>("invoiceid");
    }
    set
    {
        this.OnPropertyChanging("InvoiceId");
        this.SetAttributeValue("invoiceid", value);
        this.OnPropertyChanged("InvoiceId");
    }
}

So my InvoiceId is an EntityReference & my statuscode property is an OptionSetValue type. I have a query to return me entities that match InvoiceId && statuscode != X but record is being returned where invoice id matches but also if the statuscode.Value == X so only the first part of the where is applied or the 2nd part fails but result still added.

My query is:

    var result = (from qa in ctx.allocationSet
                                   where qa.InvoiceId.Id == invoiceId
                                   && qa.statuscode.Value != 2
                                   select qa);

So in essence if I populate 2 records in this set, 1 with InvoiceId abc-123 and statuscode = 1, then another with InvoiceId XYZ-987 with statuscode = 2, then search for invoiceId XYZ-987 my query should return zero records but this returns the 2nd record everytime even though the statuscode.Value ==2?

2

There are 2 answers

0
PAblo On

My issue appears to be related to how the data is initialised/set. If I set up the entity with the value before calling the XrmFakedContext then the query behaves as expected but if after initialisation I update the statuscode manually as below, the weirdness happens.

var allocation = ctx.allocationSet.First(x => x.InvoiceId.Id == _testInvoiceId);
            allocation.Attributes["statuscode"] = new OptionSetValue((int)allocation.statuscodeValues.Active);

Big thanks to Jordi at dynamicsvalue for help.

0
Jordi On

The query in FakeXrmEasy will return results based on the current state of the in-memory database.

If you make a change to an entity record without actually persisting it into the in-memory database (that is, without actually calling methods like service.Create, service.Update, service.Delete, and so on), then these changes won't be persisted into the database, and so, the changes won't be reflected when retrieving data from it.

This behaviour actually mimics CDS / the Organization Service. If you set an entity attribute in code, without actually saving it back to CDS / CRM / OrgService, then when you retrieve it, it won't be there because it wasn't actually updated in the real database.

So same concept with FakeXrmEasy really.