Git Product home page Git Product logo

Comments (8)

jordimontana82 avatar jordimontana82 commented on May 25, 2024

Could you post a Unit test to reproduce this, please?

from fake-xrm-easy.

Skubakoob avatar Skubakoob commented on May 25, 2024

Sure - see below... been looking into it just now and a few odd behaviours.. It seems to be related to money type fields (from what I can tell) and only when you add more than one entity to the list. Switch the money to a decimal and it works, and only add contact1 to the list and it works. Otherwise throws the error:

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

Entity contact1 = new Entity("contact");
contact1.Id = Guid.NewGuid();
contact1.Attributes["firstname"] = "Fred";
contact1.Attributes["lastname"] = "Bloggs";
contact1.Attributes["new_somefield"] = new Money(12345); // (decimal)678910 

Entity contact2 = new Entity("contact");
contact2.Id = Guid.NewGuid();
contact2.Attributes["firstname"] = "Jo";
contact2.Attributes["lastname"] = "Bloggs";
contact2.Attributes["new_somefield"] = new Money(678910); // (decimal)678910 


contactList.Add(contact1);
contactList.Add(contact2); // Comment me out, and I work OK

context.Initialize(contactList);

QueryExpression qry = new QueryExpression("contact");
qry.ColumnSet = new ColumnSet(true);
qry.AddOrder("new_somefield", OrderType.Ascending);
var results = service.RetrieveMultiple(qry);

from fake-xrm-easy.

Skubakoob avatar Skubakoob commented on May 25, 2024

Incidentally.. This works:

var query = context.CreateQuery("contact");
query = query.Select(x => x.ProjectAttributes(qe, context));
query = query.OrderBy(e => ((Money)e.Attributes["new_somefield"]).Value);
var a = query.ToList();

This doesn't:

var query = context.CreateQuery("contact");
query = query.Select(x => x.ProjectAttributes(qe, context));
query = query.OrderBy(e => e.Attributes["new_somefield"]); 
var a = query.ToList();

which is what your code in XrmFakedContext.Queries.cs is doing:

 //Sort results
if (qe.Orders != null)
{
    foreach (var order in qe.Orders)
    {
        if (order.OrderType == OrderType.Ascending)
            query = query.OrderBy(e => e.Attributes[order.AttributeName]);
        else
            query = query.OrderByDescending(e => e.Attributes[order.AttributeName]);
    }
}
return query;

from fake-xrm-easy.

jordimontana82 avatar jordimontana82 commented on May 25, 2024

Great, thx for spotting.

That is working for basic data types but it won't do it for Money nor OptionSetValues I think.... We could implement an IComparable for Money and OptionSet fields, maybe is the neatest way of doing it.

from fake-xrm-easy.

jordimontana82 avatar jordimontana82 commented on May 25, 2024

And actually EntityReference objects.... I suppose we must order by the EntityReference.Name field, to emulate the orderby of CRM.

What do you think?

from fake-xrm-easy.

Skubakoob avatar Skubakoob commented on May 25, 2024

Yep makes sense!

Thanks for the tool by the way, looking very promising!

from fake-xrm-easy.

Skubakoob avatar Skubakoob commented on May 25, 2024

I had a quick go at implementing it, I haven't got round to doing the whole github thing yet so I'll just post my changes below - I'm sure there may be a more elegant way but this is enough to stop my horrible errors for the moment if it's of any help. Entity references and option sets may need tweaking to get the actual text values in, I don't think they'll work quite right yet.

Change the sorting bit to:

//Sort results
if (qe.Orders != null)
{
    foreach (var order in qe.Orders)
    {
        // AttributeOrderBy.SortDescendingHelper
        if (order.OrderType == OrderType.Ascending)
            query = query.OrderBy(e => e.Attributes[order.AttributeName], new AttributeOrderByComparer());
        else
        {                        
            query = query.OrderByDescending(e => e.Attributes[order.AttributeName], new AttributeOrderByComparer());
        }
    }
}
return query; 

And add this class (doesn't need separate ascending/descending methods)

public class AttributeOrderByComparer : IComparer<object>
{
    public int Compare(Object objectA, Object objectB)
    {
        Type attributeType = objectA.GetType();
        if (attributeType == typeof(string))
        {
            return String.Compare(objectA.ToString(), objectB.ToString());
        }
        else if (attributeType == typeof(int))
        {
            return ((int)objectA).CompareTo(((int)objectB));
        }
        else if (attributeType == typeof(OptionSetValue))
        {
            // we'll want the text value
            OptionSetValue attributeValueA = (OptionSetValue)(objectA);
            OptionSetValue attributeValueB = (OptionSetValue)(objectB);
            return attributeValueA.Value.CompareTo(attributeValueB.Value);
        }
        else if (attributeType == typeof(DateTime))
        {
            return ((DateTime)objectA).CompareTo((DateTime)objectB);
        }
        else if (attributeType == typeof(EntityReference))
        {
            // Name might well be Null in an entity reference?
            EntityReference entityRefA = (EntityReference)objectA;
            EntityReference entityRefB = (EntityReference)objectB;
            return entityRefA.Name.CompareTo(entityRefB.Name);
        }
        else if (attributeType == typeof(Guid))
        {
            return ((Guid)objectA).CompareTo((Guid)objectB);
        }
        else if (attributeType == typeof(decimal))
        {
            return ((decimal)objectA).CompareTo((decimal)objectB);
        }
        else if (attributeType == typeof(double))
        {
            return ((double)objectA).CompareTo((double)objectB);
        }
        else if (attributeType == typeof(float))
        {
            return ((float)objectA).CompareTo((float)objectB);
        }
        else if (attributeType == typeof(Money))
        {
            Decimal valueA = ((Money)objectA).Value;
            Decimal valueB = ((Money)objectB).Value;
            var x = valueA.CompareTo(valueB);
            return x;
        }
        else if (attributeType == typeof(bool))
        {
            return ((bool)objectA).CompareTo((bool)objectB);
        }
        else
        {                   
            return 0;
        }
    }
}

from fake-xrm-easy.

jordimontana82 avatar jordimontana82 commented on May 25, 2024

Thanks a mill @Skubakoob 👍

The git process to contribute to the project is rather easy.

  1. Create a fork of the project
  2. Clone your fork using Visual Studio and the Git plugin
  3. Make any required changes
  4. Commit and Push (it will push to your fork)
  5. Now, you can submit a Pull Request with your changes that I could review & merge.

Now in relation to the changes, as it was working for basic types already, I would rather use a switch with the Money, EntityReferences and OptionSetvalues, and a default case for everything else, where we don't need to cast anything specifically.

Thanks a lot!

from fake-xrm-easy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.