0

I've tried several things and i cant manage to put this to work.

I've 2 entities. User and UserDetails (described below). I manage to add a user and it's user details but when i try to get one using the include ("UserDetails") e get the following error.

A specified Include path is not valid. The EntityType 'Floralist.Repository.Context.User' does not declare a navigation property with the name 'UserDetails'.

The entities are the following:

public class User : Entity
{
    public User()
    {
        Details = new UserDetails();
        //FlowerList = new Collection<Flower>();
    }

    public Guid Id { get; set; }

    public string Username { get; set; }

    [Index(IsUnique = true)]
    public string Email { get; set; }

    public string Password { get; set; }

    public Roles Role { get; set; }

    public UserState State { get; set; }

    public int? DetailsId { get; set; }
    public UserDetails Details { get; set; }

    public DateTime? LastLoginDate { get; set; }

    //public ICollection<Flower> FlowerList { get; set; }

    //public ICollection<Friend> FriendList { get; set; }

}

public class UserDetails : Entity
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName => $"{this.FirstName} {this.LastName}";

    public string Address { get; set; }

    public string PostalCode { get; set; }

    public DateTime BirthDate { get; set; }

    public int? WatermarkId { get; set; }

    public Blob Watermark { get; set; }

    public int? ProfilePictureId { get; set; }

    public Blob ProfilePicture { get; set; }
}

The mappings are the following:

public class UserMap : EntityTypeConfiguration<User>
{
    public UserMap()
    {
        this.HasKey(t => t.Id);

        this.ToTable("Users");

        this.Property(t => t.Id).HasColumnName("Id");

        this.Property(t => t.Username)
            .IsRequired()
            .HasMaxLength(48)
            .HasColumnName("Username");

        this.Property(t => t.Password)
            .HasMaxLength(256)
            .HasColumnName("Password");

        this.Property(t => t.Email)
            .IsRequired()
            .HasMaxLength(256)
            .HasColumnName("Email");

        this.Property(t => t.Role)
            .IsRequired()
            .HasColumnName("Role");

        this.Property(t => t.State)
            .IsRequired()
            .HasColumnName("State");

        this.Property(t => t.LastLoginDate)
            .IsOptional()
            .HasColumnName("LastLoginDate");

        this.Property(t => t.CreateDate)
            .IsRequired()
            .HasColumnName("CreateDate");

        this.Property(t => t.UpdateDate)
            .IsOptional()
            .HasColumnName("UpdateDate");

        this.Property(t => t.DetailsId)
            .HasColumnName("DetailsId");
    }
}

public UserDetailsMap()
    {
        this.HasKey(t => t.Id);

        this.ToTable("UsersDetails");

        this.Property(t => t.Id).HasColumnName("Id");

        this.Property(t => t.WatermarkId)
            .HasColumnName("WatermarkId");

        this.Property(t => t.ProfilePictureId)
            .HasColumnName("ProfilePictureId");

        this.Property(t => t.FirstName)
            .IsRequired()
            .HasMaxLength(64)
            .HasColumnName("FirstName");

        this.Property(t => t.LastName)
            .IsRequired()
            .HasMaxLength(64)
            .HasColumnName("LastName");

        this.Property(t => t.Address)
            .HasMaxLength(512)
            .HasColumnName("Address");

        this.Property(t => t.PostalCode)
            .HasMaxLength(64)
            .HasColumnName("PostalCode");

        this.Property(t => t.BirthDate)
            .HasColumnName("BirthDate");

        this.Property(t => t.CreateDate)
            .IsRequired()
            .HasColumnName("CreateDate");

        this.Property(t => t.UpdateDate)
            .IsRequired()
            .HasColumnName("UpdateDate");

        //this.HasOptional(t => t.ProfilePicture).WithMany().HasForeignKey(f => f.ProfilePictureId);
        //this.HasOptional(t => t.Watermark).WithMany().HasForeignKey(f => f.WatermarkId);
    }

And the context:

internal class FloralistContext : DbContext
{
    private const string Dbmodule = "Floralistdb";

    public FloralistContext() : base(Dbmodule)
    {
    }

    public DbSet<User> Users { get; set; }

    public DbSet<UserDetails> UserDetails { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

        modelBuilder.Configurations.Add(new UserMap());
        modelBuilder.Configurations.Add(new UserDetailsMap());
    }
}

I get the error when doing this:

            var user = Repository.Users.Include("UserDetails").FirstOrDefault(u => u.Email.Equals(email, StringComparison.InvariantCultureIgnoreCase) && u.Password.Equals(password));

If i don't specify the include path the user details comes as null.

  • Add `using System.Data.Entity;` to the top of your code file and the replace `.Include("UserDetails")` with `.Include(i => i.UserDetails)` - this should help you find the problem though my guess would be that you haven't mapped a proper relationship between the two since `UserDetails` has no virtual field of type User` to link it to the Users table – Ortund Jul 17 '17 at 14:24
  • The `Include` expects the **name** of the navigation property, which in your case is `Details` (not `UserDetails`). – Ivan Stoev Jul 17 '17 at 14:26
  • @IvanStoev well spotted. I missed that one... so it would actually be `.Include(i => i.Details)` – Ortund Jul 17 '17 at 14:34
  • @IvanStoev That did the trick but every property of the details is null even if it is filled in the db – Jonas Moniz Jul 17 '17 at 15:02
  • you haven't defined the relationship between the tables, is there any reason to do so? if you know the mapping is correct, are your FK values populated accordingly? – DevilSuichiro Jul 17 '17 at 15:17
  • @DevilSuichiro I guess so. I'm using EF code first so it should do it for me right? This is the tables http://imgur.com/a/UqnJq and the data – Jonas Moniz Jul 17 '17 at 15:20

1 Answers1

0

I finally got this to work by reading this post EF understanding association

I had to put a virtual property in User to UserDetails and in UserDetails to User and a mapping this.HasOptional(x => x.Details).WithRequired(x => x.User);

Thanks to everyone