views:

100

answers:

1

I have the following nhibernate mapping

<class name="Customer">
  <id name="Id">
    <generator class="native"/>
  </id>
  <property name="Name"/>
  <set name="Invoices" cascade="all" lazy="false">
    <key column="CustomerId"/>
    <one-to-many class="Invoice"/>
  </set>
</class>

<class name="Invoice">
  <id name="Id">
    <generator class="native"/>
  </id>
  <property name="Status"/>
</class>

With these data objects

public enum InvoiceStatus { Unpayed, Payed };

public class Customer
{
    virtual public int Id { get; private set; }
    virtual public string Name { get; set; }
    virtual public ISet<Invoice> Invoices { get; set; }
}

public class Invoice
{
    virtual public int Id { get; private set; }
    virtual public InvoiceStatus Status { get; set; }
}

When I run the following code

t = session.BeginTransaction();
session.SaveOrUpdate(new Customer
{
    Name = "Customer1",
    Invoices = new HashedSet<Invoice> { new Invoice { Status = InvoiceStatus.Payed } }
});
session.SaveOrUpdate(new Customer
{
Name = "Customer2",
    Invoices = new HashedSet<Invoice> { new Invoice { Status = InvoiceStatus.Unpayed } }
    });
session.SaveOrUpdate(new Customer
{
    Name = "Customer3",
    Invoices = new HashedSet<Invoice> {
        new Invoice {Status = InvoiceStatus.Payed},
        new Invoice {Status = InvoiceStatus.Unpayed}
    }
});
session.SaveOrUpdate(new Customer { Name = "Customer4" });
t.Commit();

Console.WriteLine("{0} customers have payed invoices", session.Linq<Customer>().Where(c => c.Invoices.Any(i => i.Status == InvoiceStatus.Payed)).ToList().Count);
Console.WriteLine("{0} customers have unpayed invoices", session.Linq<Customer>().Where(c => c.Invoices.Any(i => i.Status == InvoiceStatus.Unpayed)).ToList().Count);
Console.WriteLine("Attempt 1: {0} customers have no invoices", session.Linq<Customer>().Where(c => c.Invoices.IsEmpty).ToList().Count);
Console.WriteLine("Attempt 2: {0} customers have no invoices", session.Linq<Customer>().Where(c => c.Invoices.Count == 0).ToList().Count);
Console.WriteLine("Attempt 3: {0} customers have no invoices", session.Linq<Customer>().Where(c => c.Invoices.Count() == 0).ToList().Count);

I get

2 customers have payed invoices
2 customers have unpayed invoices
Attempt 1: 4 customers have no invoices
Attempt 2: 3 customers have no invoices
Attempt 3: 3 customers have no invoices

The last three results are not what I expected, can you explain why?
And how would I get the right results?

A: 

To answer my own question. It works when I use !c.Invoices.Any() in the Where clause

Console.WriteLine("Attempt 4: {0} customers have no invoices", session.Linq<Customer>().Where(c => !c.Invoices.Any()).ToList().Count);
fordan