Search code examples
c#linqlinq-to-sqlunionintersect

Is sql to Linq union by reference? (the same for except and intersect?)


When you perform a union in linq to sql, will it be by reference - if the reference to the object point to the same object - or is it by the id field?

Example method:

        public IEnumerable<CustomerModel> GetCustomers(string searchCriteria)
    {
        ExpressLogger.LogDebug("Enter"); 
        try
        {
            var datacontext = Helpers.Utils.GetCustomerRmhDataContext();
            using(datacontext)
            {
               var accountCustomers = datacontext.Customers.Where(c => 
                            c.AccountNumber.ToLower().Contains(searchCriteria.ToLower())).Select(c=>convertRmhToModel(c,datacontext)).ToList();

                var phoneCustomers = datacontext.Customers.Where(c =>
                            c.PhoneNumber.ToLower().Contains(searchCriteria.ToLower())).Select(c => convertRmhToModel(c, datacontext)).ToList();

                var personalNumberCustomers = datacontext.Customers.Where(c =>
                            c.TaxNumber.ToLower().Contains(searchCriteria.ToLower())).Select(c => convertRmhToModel(c, datacontext)).ToList();

                var emailCustomers = datacontext.Customers.Where(c =>
                            c.EmailAddress.ToLower().Contains(searchCriteria.ToLower())).Select(c => convertRmhToModel(c, datacontext)).ToList();


                var allCustomers = accountCustomers.Union(phoneCustomers).Union(personalNumberCustomers).Union(emailCustomers).ToList();


                return allCustomers;
            }
        }
        catch (Exception ex)
        {
            ExpressLogger.LogError(ex.Message);
            throw;
        }
    }

This function do what i want, it searches for customer for accountnumber, phone, mail and swedish personalnumber. And then i make a union and return the result. But im curios - how does this work, will it compare the union with the ID field or is it by reference - will it check hashcode and equal comparer? (is it the same for intersect and except?)


Solution

  • At this point, .Union is called on .Net collections and its behavior is defined in the docs for Enumerable.Union:

    The default equality comparer, Default, is used to compare values of the types that implement the IEqualityComparer generic interface.

    This is further clarified in the docs for EqualityComparer<T>.Default:

    The Default property checks whether type T implements the System.IEquatable<T> interface and, if so, returns an EqualityComparer<T> that uses that implementation. Otherwise, it returns an EqualityComparer<T> that uses the overrides of Object.Equals and Object.GetHashCode provided by T.

    So, if CustomerModel implements IEquatable<CustomerModel>.Equals and/or overrides Object.Equals, then Union uses one of these methods to compare customers.

    Otherwise, it falls back on default implementation of Object.Equals that compares object references:

    If the current instance is a reference type, the Equals(Object) method tests for reference equality, and a call to the Equals(Object) method is equivalent to a call to the ReferenceEquals method..