EF Feature CTP5

12/7/2010 10:51:00 PM By Felipe Pessoto

Com alguns dias de atraso, foi lançado o quinto e último CTP do Entity Framework Code First. A versão final é esperada para o final do primeiro trimestre de 2011. É importante resaltar os known issues:

  • Table & Column Mapping in the Fluent API
    We have done some work to make the mapping of classes/properties to tables/columns simpler and more intuitive in CTP5. We are still working to improve the quality of this new work, particularly around the mapping of inheritance hierarchies.
  • Pluggable Conventions 
    CTP5 includes a very early preview of this feature that is not complete and has not been extensively tested.
  • The new Validation feature is currently only supported when using Code First  


As novidades são:

  Read more...

IEqualityComparer facilitado

2/25/2010 11:16:00 PM By Felipe Pessoto

Quando usamos o Linq temos alguns extension methods muito úteis como Distinct e Except. Porém para fazer uma comparação customizada é necessário criar uma classe que herde de IEqualityComparer<T> e passar uma instancia como parâmetro, o que considero muito sujo, principalmente se cada comparar for de um jeito.

Encontrei uma solução no blog do Brendan Enrick, porém pra mim não funcionou. não sei se fiz algo errado, mas o LINQ sempre chamava primeiro o GetHashCode, que se não fosse igual já retornava false sem nem passar pelo Equals. Alterei para aceitar uma Func que será usada no GetHashCode também, assim só precisamos dessa classe e podemos fazer a chamada da seguinte forma:

List<MyObject> x = myCollection.Except(otherCollection, (x, y) => x.Codigo == y.Codigo, z => z.Codigo).ToList();

Onde "(x, y) => x.Codigo == y.Codigo" é nossa comparação, e  z => z.Codigo o GetHashCode. Assim usamos o Except ou Distinct da mesma maneira que o Where, First, Any, etc

Código:

public static class InterfaceEnumerableExtension
{
     public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first,
     IEnumerable<TSource> second, Func<TSource, TSource, bool> comparer, Func<TSource, int> hashFunction)
     {
         return first.Except(second, new LambdaComparer<TSource>(comparer, hashFunction));
     }
 }

public class LambdaComparer<T> : IEqualityComparer<T>
{
     private readonly Func<T, T, bool> lambdaComparer;
     private readonly Func<T, int> lambdaHash;

     public LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash)
     {
         if (lambdaComparer == null)
             throw new ArgumentNullException("lambdaComparer");
         if (lambdaHash == null)
             throw new ArgumentNullException("lambdaHash");

         this.lambdaComparer = lambdaComparer;
         this.lambdaHash = lambdaHash;
     }

     public bool Equals(T x, T y)
     {
         return lambdaComparer(x, y);
     }

     public int GetHashCode(T obj)
     {
         return lambdaHash(obj);
     }
}