Entity Framework - Code First - TPH and WillCascadeOnDelete(true) - ef-code-first

I have an issue when using TPH and WillCascadeOnDelete(true). When I have the value set on true for cascade on delete my database is not created. The exception message is the following one:
Introducing FOREIGN KEY constraint 'FK_dbo.MembersProfiles_dbo.Contacts_ContactId' on table 'MembersProfiles' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
In order to clear things out here is my model and the mapping used for it.
public class MemberProfile
{
public Guid MemberProfileId { get; set; }
public ICollection<Contact> Contacts { get; set; }
}
public abstract class Contact
{
public Guid ContactId { get; set; }
public Guid AddressId { get; set; }
public Address Address { get; set; }
}
public class PersonContact : Contact
{
public string Profession { get; set; }
public string OrganizationName { get; set; }
}
public class OrganizationContact : Contact
{
public string SalesPhone { get; set; }
public string ServicePhone { get; set; }
}
public class ContactMap : EntityTypeConfiguration<Contact>
{
public ContactMap()
{
ToTable("Contacts");
HasKey(c => c.ContactId);
Property(c => c.ContactId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(c => c.Name).IsRequired().HasMaxLength(50);
Property(c => c.Email).IsRequired().HasMaxLength(150);
Property(c => c.MobilePhone).IsRequired().HasMaxLength(15);
Property(c => c.Description).IsOptional().HasMaxLength(500);
Property(c => c.FixPhone).IsOptional().HasMaxLength(15);
Property(c => c.FaxNumber).IsOptional().HasMaxLength(15);
HasRequired(mp => mp.Address).WithMany().HasForeignKey(mp => mp.AddressId);
HasRequired(mp => mp.Link).WithMany().HasForeignKey(mp => mp.LinkId);
HasRequired(mp => mp.Image).WithMany().HasForeignKey(mp => mp.MediaId);
}
}
public class PersonContactMap : EntityTypeConfiguration<PersonContact>
{
public PersonContactMap()
{
Property(pc => pc.Profession).IsOptional().HasMaxLength(150);
Property(pc => pc.OrganizationName).IsOptional().HasMaxLength(150);
Map(pc => pc.Requires("Discriminator").HasValue("PersonContact").HasColumnType("nvarchar(max)")); }
}
public class OrganizationContactMap : EntityTypeConfiguration<OrganizationContact>
{
public OrganizationContactMap()
{
Property(oc => oc.SalesPhone).IsOptional().HasMaxLength(15);
Property(oc => oc.ServicePhone).IsOptional().HasMaxLength(15);
Map(oc => oc.Requires("Discriminator").HasValue("OrganizationContact").HasColumnType("nvarchar(max)"));
}
}
public class MemberProfileMap : EntityTypeConfiguration<MemberProfile>
{
public MemberProfileMap()
{
ToTable("MembersProfiles");
HasKey(mp => mp.MemberProfileId);
Property(mp => mp.MemberProfileId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(mp => mp.Name).IsRequired().HasMaxLength(50);
Property(mp => mp.DateOfBirth).IsRequired();
Property(mp => mp.Email).IsRequired().HasMaxLength(150);
Property(mp => mp.MobilePhone).IsRequired().HasMaxLength(15);
Property(mp => mp.Summary).IsOptional();
HasRequired(mp => mp.Address).WithMany().HasForeignKey(mp => mp.AddressId).WillCascadeOnDelete(true);
Property(mp => mp.AddressId).HasColumnName("AddressId");
HasOptional(mp => mp.Media).WithMany().Map(mp => mp.MapKey(new[] { "MediaId" })).WillCascadeOnDelete(true);
HasOptional(mp => mp.Tags).WithMany().Map(mp => mp.MapKey(new[] { "TagId" })).WillCascadeOnDelete(true);
HasOptional(mp => mp.Contacts).WithMany().Map(mp => mp.MapKey(new[] { "ContactId" })).WillCascadeOnDelete(true);
}
}
Unfortunately I am not able to realize what am I doing wrong... so any clue would be much appreciated.
P.S: I am using EF 5.0 Code First

See if this BlogPost helps., another option i would try to start adding relation one by one to see where it breaks rather than stacking everything at once. And sometimes it helps to just use individual property mappings rather than Fluent API like you have done. Check out different links on that blog i mentioned above.

Ok, found the issue. I have two tables referring addresses table. In my case both Contacts and MemberProfile hold a reference to Addresses table and in both cases the cascade delete was turned on. Once I turned off the cascade delete on one of the relations everything worked just fine.

Related

Automapper can't map nested collection

I'm trying to figure out how to do this mapping in automapper 9.0.0. Can anybody help me out?
I have these classes
class User
{
public string Name { get; set; }
public Address[] Addresses { get; set; }
}
class Address
{
public string StreetName { get; set; }
}
class UserDto
{
public string Name { get; set; }
public PropertiesDto Properties { get; set; }
}
class PropertiesDto
{
public AddressDto[] Addresses { get; set; }
}
class AddressDto
{
public string StreetName { get; set; }
}
My goal is to place the array of addresses inside a 'PropertiesDto' object, where there eventually will be a lot of other arrays.
var user = new User { Name = "Foo", Addresses = new[] { new Address { StreetName = "Main St." } } };
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Address[], AddressDto[]>();
cfg.CreateMap<User, UserDto>()
.ForMember(d => d.Properties.Addresses, opt => opt.MapFrom(s => s.Addresses));
});
IMapper mapper = new Mapper(config);
var dtoUser = mapper.Map<UserDto>(user);
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(dtoUser));
Console.WriteLine("Hit enter...");
Console.ReadLine();
The code fails with this error message.
Unhandled exception. System.ArgumentException: Expression 'd => d.Properties.Addresses' must resolve to top-level member and not any child object's properties. You can use ForPath, a custom resolver on the child type or the AfterMap option instead. (Parameter 'lambdaExpression')
There is a special command for just this situation - if you're mapping to a property below the top level, then just use .ForPath (as the error message suggests) in place of .ForMember. Like this:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Address[], AddressDto[]>();
cfg.CreateMap<User, UserDto>()
.ForPath(d => d.Properties.Addresses, opt => opt.MapFrom(s => s.Addresses));
});
What worked for me was using reverse mapping.
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Address, AddressDto>();
cfg.CreateMap<UserDto, User>()
.ForMember(d => d.Addresses, opt => opt.MapFrom(s => s.Properties.Addresses))
.ReverseMap();
});

How to fix the unmapped members?

I am building a new project for browsing through movies and giving your opinion for them. Now I am on the administration part and I added functionality for adding a movie but when I try to add a movie the automapper throws exception for unmapped members on the service where I am mapping dto to data model. The members are from the base data model for example the id.
EDIT:
I tried to ignore all the members that make this exception, also tried to made a constructor with no arguments but doesn't work.
// Initialization
Mapper.Initialize(conf =>
{
conf.CreateMap<Movie, MovieDto>();
conf.CreateMap<MovieDto, Movie>();
conf.CreateMap<MovieDto, MovieViewModel>();
});
// Base Data Model
public class DataModel
{
[Key]
public int Id { get; set; }
[DataType(DataType.DateTime)]
public DateTime? CreatedOn { get; set; }
[DataType(DataType.DateTime)]
public DateTime? ModifiedOn { get; set; }
public bool IsDeleted { get; set; }
[DataType(DataType.DateTime)]
public DateTime? DeletedOn { get; set; }
}
// Movie Data Model
public class Movie: DataModel
{
public Movie(string title, double rating, string duration, string type, string description, DateTime releaseDate, string producer)
{
this.Title = title;
this.Rating = rating;
this.Duration = duration;
this.Type = type;
this.Description = description;
this.ReleaseDate = releaseDate;
this.Producer = producer;
}
// successfully mapped members
}
// Movie DTO
public class MovieDto
{
public string Title { get; set; }
public double Rating { get; set; }
public string Duration { get; set; }
public string Type { get; set; }
public string Description { get; set; }
public DateTime ReleaseDate { get; set; }
public string Producer { get; set; }
}
// Add functionality
public void AddMovie(MovieDto movie)
{
//execption here
var movieDM = this.mapper.Map<Movie>(movie);
this.repo.Add(movieDM);
this.saver.SaveChanges();
}
This is the exception on img: https://i.imgur.com/RGZP6NP.png
Got it to work by doing the following.
Firstly, since DataModel is a base class, I followed automapper's mapping inheritance (see docs).
Then since you are using a mapper instance to map this.mapper.Map<Movie>(movie), the configuration needs to be instance rather than static as well, and I use the AutoMapper.Extensions.Microsoft.DependencyInjection nuget package for this, which allows registering Automapper with the IoC container.
My configuration looks like this (inside the ConfigureServices method of the Startup class).
services.AddAutoMapper(conf =>
{
conf.CreateMap<object, DataModel>()
.ForMember(d => d.Id, opts => opts.Ignore())
.ForMember(d => d.CreatedOn, opts => opts.MapFrom(_ => DateTime.Now))
.ForMember(d => d.ModifiedOn, opts => opts.MapFrom(_ => DateTime.Now))
.ForMember(d => d.DeletedOn, opts => opts.MapFrom(_ => (DateTime?)null))
.ForMember(d => d.IsDeleted, opts => opts.MapFrom(_ => false))
.Include<MovieDto, Movie>();
conf.CreateMap<Movie, MovieDto>();
conf.CreateMap<MovieDto, Movie>();
});
Note that I used CreateMap<object, DataModel> for the base class mapping and just used hardcoded values for dates there, feel free to adjust to suit your scenario.
After injecting an instance of IMapper, I was able to call this.mapper.Map<Movie>(movie) successfully.
Hope this sets u off in a good direction.
You can specify that AutoMapper should not validate that all properties are being mapped. The MemberList enum can be used for this when creating the mapping configuration. For example:
conf.CreateMap<MovieDto, Movie>(MemberList.None)
The error in the screenshot however indicates that another mapping is problematic, the one from MovieViewModel to MovieDto. I suggest you add a mapping configuration for these types as well:
conf.CreateMap<MovieViewModel, MovieDto>(MemberList.None)
You could try Profile Instances.
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<OrderViewModel, Order>()
.ForMember(dest => dest.OrderItem, opt => opt.MapFrom(src => src.OrderItemViewModel));
CreateMap<OrderItemViewModel, OrderItem>();
CreateMap<Order, Order>()
.ForMember(dest => dest.Id, opt => opt.Ignore());
CreateMap<Movie, MovieDto>();
CreateMap<MovieDto, Movie>();
}
}
Here is the working demo AutoMapperProfile

Mapper Dto to Entity in EF using self many to many relationship

I have a project with 4 classes:Direction, Area, Section and Local. Direction have many areas, Area have many sections and section have many locals. Local have positives locals and negatives locals, therefore Local entity will have a self many to many relationship. I'm using Automapper for convert LocalDto to Local, but when i try to update this entity with positives locals and/or negatives locals inserted, the system generate this exception:
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
So, they are my mapper classes for my entities:
*******DirectionMapper*******
public static class DirectionMappers
{
public static void SettingMappingDirectionToDirectionDto()
{
Mapper.CreateMap<Direction, DirectionDto>()
.ForMember(directionDto => directionDto.AreasDtosList,
mc => mc.MapFrom(direction => direction.AreasCollection));
}
public static void SettingMappingDirectionDtoToDirection()
{
Mapper.CreateMap<DirectionDto, Direction>()
.ForMember(direction => direction.AreasCollection,
mc => mc.MapFrom(directionDto => directionDto.AreasDtosList));
}
public static void SettingMappingDirectionToString()
{
Mapper.CreateMap<Direction, string>().ConvertUsing(direction => direction.Name ?? string.Empty);
}
}
********AreaMapper**********
public class AreaMappers
{
public static void SettingMappingAreaToAreaDto()
{
Mapper.CreateMap<Area, AreaDto>()
.ForMember(areaDto => areaDto.SectionsDtosList, mc => mc.MapFrom(area => area.SectionsCollection))
.ForMember(areaDto => areaDto.DirectionDto, mc => mc.MapFrom(area => area.Direction));
}
public static void SettingMappingAreaDtoToArea()
{
Mapper.CreateMap<AreaDto, Area>()
.ForMember(area => area.SectionsCollection, mc => mc.MapFrom(areaDto => areaDto.SectionsDtosList))
.ForMember(area => area.Direction,mc=> mc.MapFrom(areaDto=> areaDto.DirectionDto));
}
public static void SettingMappingAreaToString()
{
Mapper.CreateMap<Area, string>().ConvertUsing(area => area.Name ?? string.Empty);
}
}
******SectionMapper*******************
public class SectionMappers
{
public static void SettingMappingSectionToSectionDto()
{
Mapper.CreateMap<Section, SectionDto>()
.ForMember(sectionDto => sectionDto.LocalsDtosList, mc => mc.MapFrom(section => section.LocalsCollection))
.ForMember(sectionDto => sectionDto.AreaDto, mc => mc.MapFrom(section => section.Area));
}
public static void SettingMappingSectionDtoToSection()
{
Mapper.CreateMap<SectionDto, Section>()
.ForMember(section => section.LocalsCollection,
mc => mc.MapFrom(sectionDto => sectionDto.LocalsDtosList))
.ForMember(section => section.Area, mc => mc.MapFrom(sectionDto => sectionDto.AreaDto));
}
public static void SettingMappingSectionToString()
{
Mapper.CreateMap<Section, string>().ConvertUsing(section => section.Name ?? string.Empty);
}
}
******LocalMapper (the main course)******
public static class LocalMappers
{
public static void SettingMappingLocalToLocalDto()
{
Mapper.CreateMap<Local, LocalDto>()
.ForMember(localDto => localDto.PositivesLocalsDtos,
mc => mc.MapFrom(local => local.PositivesLocals)
)
.ForMember(localDto => localDto.NegativesLocalsDtos,
mc => mc.MapFrom(local => local.NegativesLocals)
)
.ForMember(localDto => localDto.SectionDto, mc => mc.MapFrom(local => local.Section));
}
public static void SettingMappingLocalDtoToLocal()
{
Mapper.CreateMap<LocalDto, Local>()
.ForMember(local => local.PositivesLocals,
mc => mc.MapFrom(localDto => localDto.PositivesLocalsDtos)
)
.ForMember(local => local.NegativesLocals,
mc => mc.MapFrom(localDto => localDto.NegativesLocalsDtos)
)
.ForMember(local => local.Section, mc => mc.MapFrom(localDto => localDto.SectionDto));
}
public static void SettingMappingLocalToString()
{
Mapper.CreateMap<Local, string>().ConvertUsing(local => local.Number ?? string.Empty);
}
}
Well, this's a service method for Local update:
public AppOperationResult Update(int id, LocalDto localDto)
{
var appOperationResult = CommunValidations.IsDtoNull(localDto);
if (appOperationResult != null) return appOperationResult;
var tupleValidation = localDto.IsModelDtoValidateForUpdate(id);
var isValidate = tupleValidation.Item1;
if (isValidate)
{
if (TryUpdateLocalFromLocalDto(id, localDto)) return AppOperationResult.Successful();
}
string messageError = tupleValidation.Item2;
return AppOperationResult.WithError(messageError);
}
And these are the methods I did to add positive and negative locals (i call them AdjacentLocals):
public AppOperationResult AddAdjacentLocalsToLocal(AdjacentLocalsToLocalDto adjacentLocalsToLocal)
{
var localDto = adjacentLocalsToLocal.LocalToModify;
var appOperationResult = CommunValidations.IsDtoNull(localDto);
if (appOperationResult != null) return appOperationResult;
var tupleValidation = localDto.IsModelDtoValidate();
var isValidate = tupleValidation.Item1;
if (isValidate)
{
if (TryToAddAdjacentLocalsToLocal(adjacentLocalsToLocal, localDto))
return AppOperationResult.Successful();
}
string messageError = tupleValidation.Item2;
return AppOperationResult.WithError(messageError);
}
private bool TryToAddAdjacentLocalsToLocal(AdjacentLocalsToLocalDto adjacentLocalsToLocal, LocalDto localDto)
{
var positiveLocals = adjacentLocalsToLocal.PositiveLocals;
var negativeLocals = adjacentLocalsToLocal.NegativeLocals;
var positiveslocalsRepeated = positiveLocals.Intersect(localDto.PositivesLocalsDtos);
positiveLocals.RemoveAll(x => positiveslocalsRepeated.Contains(x));
var negativeslocalsRepeated = negativeLocals.Intersect(localDto.NegativesLocalsDtos);
negativeLocals.RemoveAll(x => negativeslocalsRepeated.Contains(x));
localDto.PositivesLocalsDtos = new List<LocalDto>(positiveLocals);
localDto.NegativesLocalsDtos = new List<LocalDto>(negativeLocals);
return TryUpdateLocalFromLocalDto(localDto.Id, localDto);
}
private bool TryUpdateLocalFromLocalDto(int idLocal, LocalDto localDto)
{
var local = _localServices.GetById(idLocal);
local.PositivesLocals.Clear();
local.NegativesLocals.Clear();
_localServices.Update(local);
if (local != null)
{
localDto.Id = idLocal;
var localUpdated = _mappingServices.Map(localDto, local);
_localServices.Update(localUpdated);
return true;
}
return false;
}
********LocalDto*************
public class LocalDto
{
public int Id { get; set; }
public string Number { get; set; }
public float Volumen { get; set; }
public int NumberMaxPeople { get; set; }
public SectionDto SectionDto { get; set; }
public List<LocalDto> PositivesLocalsDtos { get; set; }
public List<LocalDto> NegativesLocalsDtos { get; set; }
}
I'm working using ASP.NET WEB API philosophy,that's why I pass the list of adjacent places with a JSON (correctly), because I think the relationship between the objects in the lists with the database record is lost, but I do not understand why, since these local DTOs they are mapped correctly and return the corresponding local object. However, when I update a local with out a any list of positives or negatives locals, no problem.. so i think that problem is with the self many to many relationship.
I have traced the code several times, I check if all the entities have their relationships and everything seems to be fine, but when I try to update the Local entity inserting adjacents locals(positive and negative local) gives me the error that I mentioned above. So, i . I await your answers.Regards
I think what is happening is the following some entity entity framework that is not linking the existing sections in your database when you use the service of automapper, so I suggest that in your Dto not use the relationships for the other dto, for example:
public class LocalDto
{
public int Id { get; set; }
public string Number { get; set; }
public float Volumen { get; set; }
public int NumberMaxPeople { get; set; }
public SectionDto SectionDto { get; set; }
public List<LocalDto> PositivesLocalsDtos { get; set; }
public List<LocalDto> NegativesLocalsDtos { get; set; }
}
change it to :
public class LocalDto
{
public int Id { get; set; }
public string Number { get; set; }
public float Volumen { get; set; }
public int NumberMaxPeople { get; set; }
public int SectionId { get; set; }
public List<LocalDto> PositivesLocalsDtos { get; set; }
public List<LocalDto> NegativesLocalsDtos { get; set; }
}
and you must also change the mapper associated with these entities,this must be removed from the class LocalMappers,
.ForMember(localDto => localDto.SectionDto, mc => mc.MapFrom(local => local.Section));
This solution is for all your Dtos that have relations, link them to the id of the entity with which it is related not with the Dtos
I hope I've helped

DBContext Method not found (System.MissingMethodException on OnModelCreating())

I've been stuck with below exception from OnModelCreating() in DBContext and struggling to find the cause or a solution. Can't find much help online either.
{System.MissingMethodException: Method not found: 'System.Nullable`1<Int32> Models.Application.get_AddrSeqNum()'. at Data.Configuration.ApplicationConfiguration..ctor()
Any help or ideas please?
Details:
I've two entity types 'Application' and 'Organization' and their Entity Type Configurations as below:
public class Application
{
public int ApplId { get; set; }
public int? OrganizationId { get; set; } // Compsite FK (maps to ExternalId in Organization)
public int? AddrSeqNum { get; set; } // Compsite FK (maps to AddrSeqNum)
public virtual Organization Organization { get; set; }
}
public class Organization
{
public int Id { get; set; }
/// <summary>
/// Organization ID
/// </summary>
public int ExternalId { get; set; }
public int AddrSeqNum { get; set; }
}
public class ApplicationConfiguration : EntityTypeConfiguration<Application>
{
ToTable("Application");
HasKey(e => e.ApplId)
.Property(e => e.ApplId)
.HasColumnName("appl_id")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Property(e => e.AddrSeqNum)
.HasColumnName("addr_seq_num");
// Relationship
HasOptional(e => e.Organization)
.WithMany()
.HasForeignKey(e => new { e.OrganizationId, e.AddrSeqNum });
}
public class OrganizationConfiguration : EntityTypeConfiguration<Organization>
{
public OrganizationConfiguration()
{
ToTable("Organization");
HasKey(e => new { e.ExternalId, e.AddrSeqNum }); // Compsite Unique key in table
Property(e => e.ExternalId)
.HasColumnName("external_id");
Property(e => e.AddrSeqNum)
.HasColumnName("addr_sequence");
Property(e => e.Id)
.HasColumnName("Id") // Primary key (auto increment)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
DBContext:
public partial class AppDbContext : DbContext
{
public AppDbContext ()
{
Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = false;
//Configuration.AutoDetectChangesEnabled = false;
DbInterception.Add(new FtsInterceptor());
Database.Log = (msg) => Logger.Debug(msg);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Configurations // <<- Exception from here
.Add(new ApplicationConfiguration())
.Add(new OrganizationConfiguration())
base.OnModelCreating(modelBuilder);
}
}
It was a weird situation, the references to the project that has my pocos were out of sync and were not getting rebuilt when I built my solution. One of the project is a Workflow console app targeting x86 platform. I changed to AnyCPU for all the projects in my sln. And magically ot worked again.
I was trying to add a new column/property to ine of my poco entity.
I was having this problem too, because I made a nullable database column non-nullable and Visual Studio didn't seem to want to cooperate with the change.
Deleting bin and obj folders, as well as rebuilding, didn't seem to do it.
As a workaround, I just made it nullable again. It's interesting because I'm not sure where VS is caching the nullable part--a question to be answered when I'm under less tight deadlines. :)

NHibernate Relations

I am working with NHibernate and I get this code below:
public class User
{
public User()
{
public virtual int Id { get; set; }
public virtual IList<UserConfirmation> UserConfirmation { get; set; }
public virtual string Email;
}
public User()
{
UserConfirmation = new List<UserConfirmation>();
}
}
public class UserConfirmation
{
public virtual int Id { get; set; }
public virtual User { get; set; }
}
public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.Id);
Map(x => x.Email);
HasMany(x => x.UserConfirmation)
.Inverse()
.Cascade.All();
Table("user");
}
}
public class UserConfirmationMap : ClassMap<UserConfirmation>
{
public UserConfirmationMap()
{
Id(x => x.Id);
References(x => x.User);
Table("user_confirmation");
}
}
But when I try to query over like this:
QueryOver<UserConfirmation>().Where(x => x.User.Email).Take(1).SingleOrDefault()
Than it says I do not have the property User.Email.
How can I solve this problem?
Problem is you are using x => x.User.Email
this should be done with another alias, which would be user
UserConfirmation userConfirmationAlias;
User userAlias;
QueryOver<UserConfirmation>(() => userConfirmationAlias)
.joinAlias(() => userConfirmationAlias.User , () => userAlias)
.Where(() => userAlias.Email).Take(1).SingleOrDefault()
something like above should do the trick
I think you want something like this.
QueryOver<User>().Where(x => x.Email).Take(1).SingleOrDefault()
x should be a user already. If it's not I would use the intellisense to see what type it thinks it is.
Try doing:
IQueryOver<UserConfirmation,User> qo = _Session.QueryOver<UserConfirmation,User>().Where(x => x.User.Email).Take(1).SingleOrDefault();
You could use LINQ instead of QueryOver:
Query<UserConfirmation>().Where(x => x.User.Email).Take(1).SingleOrDefault()
BTW, .Take(1).SingleOrDefault() is probably not needed. If Email is unique, .SingleOrDefault() will be enough. Otherwise, you can use .FirstOrDefault()

Resources