Entity Framework Core не привязывает первичный ключC#

Место общения программистов C#
Ответить
Anonymous
 Entity Framework Core не привязывает первичный ключ

Сообщение Anonymous »

Я использую Entity Framework Core в приложении .NET Core и столкнулся с некоторыми странными проблемами. Когда я пытаюсь получить ранее сохраненный объект, первичный ключ объекта имеет значение NULL, хотя он установлен в базе данных.
Пример/код:

Код: Выделить всё

public class Context : DbContext
{
public DbSet Users { get; set; }
public DbSet UserDatas { get; set; }
public DbSet Sessions { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
CreateRelationships(modelBuilder);
CreateIndexs(modelBuilder);
}

private void CreateRelationships(ModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasOne(e => e.UserData)
.WithOne(e => e.User)
.HasForeignKey(e => e.UserID)
.IsRequired();

modelBuilder.Entity()
.HasOne(e => e.Session)
.WithOne(e => e.User)
.HasForeignKey(e => e.UserID)
.IsRequired();

modelBuilder.Entity()
.Navigation(u => u.Session)
.AutoInclude();

modelBuilder.Entity()
.Navigation(u => u.UserData)
.AutoInclude();
}

public bool GetUserByCondition(System.Linq.Expressions.Expression predicate, out User? user)
{
user = Users.FirstOrDefault(predicate);

if (user == null)
{
return false;
}

Log.LogToDB($"UserData is null: {user.UserData == null}");
Log.LogToDB($"Session is null: {user.Session == null}");
Log.LogToDB($"User ID: {user.UserID}");

// TODO: Figure out why eager loading isn't working
Entry(user).Reference(u => u.Session).Load();
Log.LogToDB($"Session ID: {user.Session.SessionID}");

Entry(user).Reference(u => u.UserData).Load();
Log.LogToDB($"UserData ID: {user.UserData.UserDataID}");

// for some reason the context will think all of these are being added after updating them and calling .SaveChanges(). Manually attach them to fix this
Attach(user);
Attach(user.Session);

// Exception throwing because user.UserData.UserDataID = 0 / is unset
Attach(user.UserData);

return true;
}
}

public class User : IUser
{
[Key]
public long UserID { get; set; }
public UserData UserData { get; set; }
public Session Session { get; set; }

protected User() { }

public User(Context db)
{
UserData ud = new UserData(this);
UserData = ud;
db.UserDatas.Add(ud);
}
}

public class Session : ISession
{
[Key]
public long SessionID { get; set; }
public long UserID { get; set; }
public User User { get; set; }

protected Session() { }

static public Session CreateSessionForUser(User user, out string token)
{
Session session = new Session()
{
UserID = user.UserID,
User = user,
};

return session;
}
}

static public class SessionHelper
{
static public void CreateNewSessionForUser(Context db, User user)
{
Session newSession = Session.CreateSessionForUser(user, out token);

db.Sessions.Add(newSession);
db.SaveChanges();
}
}

public class UserData : IUserData
{
[Key]
public long UserDataID { get; set; }
public long UserID { get; set; }
public User User { get; set; }
}
Странное поведение происходит в GetUserByCondition. Первая проверка журнала, если user.UserData == null, выведет false, а вторая проверка журнала user.Session == null выведет true, несмотря на то, что указаны обе навигации. как AutoInclude в OnModelCreating.
После ручной загрузки сеанса через

Код: Выделить всё

Entry(user).Reference(u => u.Session).Load();
печать user.Session.SessionID выведет правильный идентификатор. Однако попытка сделать то же самое с UserData выведет значение null или 0 в зависимости от того, переключу ли я UserDataID на значение NULL или нет. Я подтвердил, что все три объекта находятся в базе данных и что все внешние ключи/связи настроены.
[img]https:// i.sstatic.net/pWEu0gfg.png[/img]

Изображение

Изображение

Любая помощь в объяснении того, почему Entity Framework Core не может получить первичный ключ в UserDatas, будет оценена по достоинству

Подробнее здесь: https://stackoverflow.com/questions/783 ... rimary-key
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»