Sort an EntityCollection with SortExpression?

Posts   
 
    
Posts: 93
Joined: 13-Feb-2008
# Posted on: 16-Apr-2008 21:01:12   

Is there a way to sort an EntityCollection<T> using a SortExpression?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 17-Apr-2008 07:40:35   

Hi Becker,you can't do that directly in EntityCollections, however you can do that via EntityView(2). Please read LLBLGenPro Help - Using the generated code - (Adapter or SelfServicing) - Using entityvies with entitycollections - Filtering and sorting.

David Elizondo | LLBLGen Support Team
Posts: 93
Joined: 13-Feb-2008
# Posted on: 17-Apr-2008 15:23:10   

Ok, thats what I thought. Unfortunately that doesn't work for me in this particular scenario. I'll create a custom compare operation to work it out.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 17-Apr-2008 16:02:06   

Ok, thats what I thought. Unfortunately that doesn't work for me in this particular scenario

Would you please specify what do you mean by "doesn't work"?

Would you please post a code snippet of what you are trying to do?

Posts: 93
Joined: 13-Feb-2008
# Posted on: 17-Apr-2008 17:51:29   

Doesn't work in that using an entityview will not accomplish what I want to accomplish (see attached snippets). I've developed a "caching" data access adapter and I'm supporting sort expressions on entitycollections at the adapter level. For instance, if an entity is in the cache list, the first time any entity of that type is requested I fetch the entire collection and store it away ignoring the sort, and the predicate, etc. After the fetch (and on subsequent fetches) i apply the requested sort/predicate/top expressions to the cached collection. I don't support prefetch paths for cached entities (mostly code tables anyway). If a single entity is requested i copy the data from the cached entity and set isnew, isdirty, etc to false.

This is meant to support very simple caching with a manual expire for code table type entities. Honestly I just wanted to see if I could get it to work. The business layer is totally oblivious to the cache so that if i remove an entity type from the cache list I don't have to change anything and the data will be fetched from the database every time.

Below are some snippets, if you are interested in seeing the whole cache enabled data access adapter i can probably post it



        private void ApplySortExpression(IEntityCollection2 collectionToFill,
            ISortExpression sortClauses)
        {
            if (sortClauses != null && sortClauses.Count > 0)
            {
                List<EntityBase2> list = new List<EntityBase2>();

                foreach (EntityBase2 temp in collectionToFill)
                {
                    list.Add(temp);
                }

                list.Sort(new CustomCompare(sortClauses));
                collectionToFill.Clear();

                foreach (EntityBase2 temp in list)
                {
                    collectionToFill.Add(temp);
                }
            }
        }

from the custom compare class


            public int Compare(EntityBase2 x, EntityBase2 y)
            {
                ISortClause clause;
                this.clauseEnum = clauses.GetEnumerator();
                int result = 0;

                while (clauseEnum.MoveNext())
                {
                    clause = clauseEnum.Current as ISortClause;

                    object field1 = x.Fields[clause.FieldToSortCore.Name].CurrentValue;
                    object field2 = y.Fields[clause.FieldToSortCore.Name].CurrentValue;

                    if (clause.FieldToSortCore.DataType.Equals(typeof(string)))
                    {
                        result = field1.ToString().CompareTo(field2.ToString());
                    }
                    else if (clause.FieldToSortCore.DataType.Equals(typeof(int)))
                    {
                        result = Convert.ToInt32(field1).CompareTo(Convert.ToInt32(field2));
                    }
                    else if (clause.FieldToSortCore.DataType.Equals(typeof(DateTime)))
                    {
                        result = Convert.ToDateTime(field1).CompareTo(field2);
                    }
                    else if (clause.FieldToSortCore.DataType.Equals(typeof(double)))
                    {
                        result = Convert.ToDouble(field1).CompareTo(Convert.ToDouble(field2));
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                    if (result != 0)
                    {
                        if (clause.SortOperatorToUse == SortOperator.Descending)
                        {
                            result = -result;
                        }
                        break;
                    }
                }

                return result;
            }

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 18-Apr-2008 10:30:54   

i apply the requested sort/predicate/top expressions to the cached collection

You can apply sorts and predicates to an EntityView, and then you can copy entities from the entityView to a new entity collection by calling ToEntityCollection() method. And this can replace the cached collection.

Posts: 93
Joined: 13-Feb-2008
# Posted on: 18-Apr-2008 13:48:27   

Thats a good idea. Just have to remember that the collectionToFill isn't passed by reference so I still have to clear collectionToFill and copy the new collection created from the call to ToEntityCollection() back into the collectionToFill. Also make sure to call ToEntityCollection() before calling clear on collectionToFill.