EF CORE 2.0 jeden-do-jeden -

0

czesc, chcę sobie zrobic prostą relację jeden-do-jeden
user<-->userDetails

klasa Users:

   [Required]
        public string Name{get;set;}

        public string DisplayName{get;set;}

        [Required]
        public char Gender{get;set;}

        [Required]
        public DateTime BirthDate{get;set;}

        public User(string n, string dn, char g, DateTime bd)
        {
            Name=n; DisplayName = dn; Gender = g; BirthDate = bd;
            UserDetails = new UserDetails(this);
        }

        public UserDetails UserDetails { get; set; }

        protected User(){}
}

Klasa UserDetails:

 protected UserDetails()
       {

       }
       public UserDetails(User user)
       {
           this.UserId = user.Id;
           this.User = user;
       }
       public int Id { get; set; }
       public int Width { get; set; }
       public int Heigth { get; set; }
       public string Region { get; set; }
       public string City { get; set; }
       public int Tattos { get; set; }
       //public IList<UsersDetailsDictionaryItems> DetailsDictionaryItems { get; set; }

       public User User { get; set; }
       public int UserId { get; set; }
}

i teraz muszę użyć EF fluent:

 protected override void OnModelCreating(ModelBuilder modelBuilder)
       {
           modelBuilder.Entity<User>()
               .HasOne<UserDetails>(x => x.UserDetails)
               .WithOne(ud => ud.User)
               .HasForeignKey<UserDetails>(ud => ud.UserId);
       }

       public DbSet<User> Users { get; set; }
       public DbSet<Message> Messages { get; set; }
       public DbSet<UserDetails> UsersDetails { get; set; }

I spoko, dodaje się user details, fragment kodu który za to odpowiada :

using (var dbc = new SomeDbContext())
         {
             var dao = new UsersDao(dbc);
             var user = dao.Get(userId);
             if (user == null)
                 throw new ArgumentOutOfRangeException(string.Format("Brak usera {0}", userId));

             if(user.UserDetails == null)
             {
                 user.UserDetails = new UserDetails(user);
                 dao.InsertUserDetails(user.UserDetails);
             }
             UpdateDetails(user.UserDetails, dto, dao);
             dbc.SaveChanges();
         }

jednak za drugim razem, wywołując tą samą metodę z tym samym userem, na warunku

if(user.UserDetails == null)

wchodzi... tak jak by nie umiał skumać user.UserDetails
o co tu chodzi?
chciałbym się odwoływać w ten sposób, a nie przez :

dbc.UserDetails.Where(x=> x.UserId == ...).SingleOrDefault();

postępowałem według tego :
http://www.entityframeworktutorial.net/efcore/configure-one-to-one-relationship-using-fluent-api-in-ef-core.aspx

1

Spróbuj coś takiego

var user = dbc.Users.Include(b => b.UserDetails).FirstOrDefault(a => a.UserId == userId);

w tym miejscu

var user = dao.Get(userId);
0

dzięki, rozumiem, że to przez lazy loading. Ale dlaczego gdy użyłem VIRTUAL dla pól "nawigacyjnych" - czyli
w Users.cs -> public virtual UserDetails UserDetails{get;set;}
w UserDetails.cs -> public virtual User User{get;set;}

to EF dalej nie robi złączenia ?
Przecież gdy pole jest virtual, to przy odwołaniu się do niego (czyli tutaj user.UserDetails) EF powinien na szybko załadować to pole...

aha, teraz doczytałem odnośnie lazy loading

This feature was introduced in EF Core 2.1.

1 użytkowników online, w tym zalogowanych: 0, gości: 1