2

a Venue can have one or more Areas and, inversely, each Area has exactly one Venue. I'm using build 1.0.0.636 of Fluent NHibernate.

When I added Fetch.Join() to the VenueMap to eliminate lazy loading, the SQL generated includes a join back to the Area table, from itself: (simplified, obviously)

SELECT *  
FROM Areas  
LEFT OUTER JOIN Venues on Areas.VenueId = Venues.Id  
LEFT OUTER JOIN Areas as Areas2 on Venues.Id = Areas2.VenueId  

This causes it to return duplicate rows so each Venue has duplicate Areas in it's collection. I've tried using MoreLinq's DistinctBy after getting all Areas, but this still leaves each Venue having duplicate Areas - it just removes duplicate areas from the main collection. It also feels really filthy as I'm returning about three times as much data and then throwing it away.

As I alluded to above, my query is to get all Areas and have all Venues eager loaded.

Domain entities:

class Venue
{
int Id;
IList Areas;
}  
class Area
{
int Id;
Venue Venue;
}

Mappings:

public class VenueMap : ClassMap<Venue>  
    {  
        public VenueMap()  
        {  
        Table("Venues");   
                HasMany(v => v.Areas)  
                .KeyColumn("VenueId")  
                .Inverse()  
                .Fetch.Join();  
        }  

public class AreaMap : ClassMap<Area>  
    {  
        public AreaMap()  
        {  
            Table("Areas");  
            Id(a => a.Id);  
            References(a => a.Venue).Column("VenueId").Not.Nullable();  
        }  
    }  

Any ideas how I can sort my mappings out and remove the duplicate Areas? I've done sooo much Googling already...

Thanks, Monty

Ilya Kogan
  • 21,995
  • 15
  • 85
  • 141
Monty
  • 119
  • 2
  • 9

1 Answers1

1

So does specifying .Not.LazyLoad() rather than Fetch.Join() in VenueMap on the Areas HasMany not work?

UPDATE What might work better is to get rid of the Fetch.Join() in your mapping and to use a Criteria query like so.

session.CreateCriteria<Area>()
.CreateAlias("Venue", "venue", JoinType.LeftOuterJoin)
.List<Area>()
Vadim
  • 17,897
  • 4
  • 38
  • 62
  • it does, to an extent - but I'm getting (and caching) ~15,000 Areas and .Not.LazyLoad() issues a SQL query for each one of these which is simply not an option. Thanks for the quick reply, though, Yads. – Monty Jan 17 '11 at 15:39
  • possibly, though I'm not sure of the criteria syntax and need to rewrite the following incredibly simple Linq query - if you can help? Session.Linq().Where(a => a.Venue.StatusId != 2). I'd really rather stick with Linq but if it does the trick this once... – Monty Jan 17 '11 at 16:05
  • think I got it but it's not correct - gives the same dupes so I'm guessing is creating exactly the same SQL. Session .CreateCriteria() .CreateAlias("Venue", "venue", JoinType.LeftOuterJoin) .Add(Restrictions.Not(Restrictions.Eq("venue.StatusId", 2))) .List(); – Monty Jan 17 '11 at 16:22
  • scratch that, I was being an idiot and had forgotten to remove the Fetch.Join() from the mapping... That might have worked - just need to watch the SQL output to ensure it's not going to lazy load and will report back – Monty Jan 17 '11 at 16:27
  • no, I'm afraid that's doing lazy loading. Thanks again for the help, Yads – Monty Jan 17 '11 at 16:29
  • anyone? This is holding me up really badly. Anyone from the FNH team out there? – Monty Jan 18 '11 at 09:22