Как привести базовый класс к производному классу, используя Entity Framework - PullRequest
0 голосов
/ 10 апреля 2019

Я пытаюсь привести базовый объект к производному объекту класса, используя Entity Framework.

Я пытался использовать конструктор копирования. Сам конструктор работает, но фреймворк выдает ошибки.

Модельные классы:

public class Member
{
    [Key]
    public string SRU { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public virtual Address Address { get; set; }

}

public class Player : Member
{
    public virtual PlayerPosition Position { get; set; }
    public virtual Doctor Doctor { get; set; }
    public virtual HealthIssue HealthIssue { get; set; }

    public Player()
    {

    }
    public Player(Member m)
    {
        SRU = m.SRU;
        Name = m.Name;
        Email = m.Email;
        Address = m.Address;
    }
}

Моя попытка:

DatabaseModel db = new DatabaseModel();

var val = db.Members
            .FirstOrDefault(b => b.Name == "Frank");

val = new Player(val);
db.Members.Update(val);

// Save changes in database
db.SaveChanges();

Я ожидал обновить эту сущность, но выдает ошибку:

System.InvalidOperationException: «Экземпляр типа объекта« Player »не может быть отслежен, поскольку другой экземпляр с таким же значением ключа для {'SRU'} уже отслеживается.

При присоединении существующих объектов убедитесь, что присоединен только один экземпляр объекта с данным значением ключа.

Edit:

Я пробовал, но я меняю имя, но тип все тот же.

DatabaseModel db = new DatabaseModel();

var val = db.Members
            .FirstOrDefault(b => b.Name == "Yordan");
db.Entry(val).State = EntityState.Detached;

var val2 = new Player(val);
val2.Name = "Frank";

db.Members.Update(val2);
db.SaveChanges();

Sample data

Итак, я получил Участника и Игрок продлил Участника. В этом случае я хочу разыграть Member в Player.

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

Я подошел к теме с другой стороны и создал свои собственные базы данных и использовал генерацию контекста из существующей базы данных.

Diagram

КакВ результате я получил такой шаблон контекста

        public virtual DbSet<Member> Members { get; set; }
        public virtual DbSet<Player> Players { get; set; }
        public virtual DbSet<Senior> Seniors { get; set; }

И три сгенерированные модели

public partial class Member
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public virtual Player Player { get; set; }
    }
public partial class Player
    {
        public int Id { get; set; }
        public string Position { get; set; }

        public virtual Member Member { get; set; }
        public virtual Senior Senior { get; set; }
    }
public partial class Senior
    {
        public int Id { get; set; }
        public string Kin { get; set; }

        public virtual Player Player { get; set; }
    }

Это единственное решение этой проблемы или, возможно, есть какие-либо альтернативы или проверенные конструкции.Я не знаю, если это решение хорошо, потому что я сделал это интуитивно.С одной стороны, это имеет смысл, потому что все части имеют общий ключ и отношение 1-1, как в наследовании.

Редактировать:

резюме: я нашел информацию изEF Core не поддерживает такое решение, и единственный вариант - использовать хранимую процедуру или дискриминатор изменений вручную, если мы используем одну таблицу.

0 голосов
/ 10 апреля 2019

val объект, который вы пытаетесь обновить, является новым объектом и имеет тот же ключ, что и тот, который вы получили из базы данных. Поскольку ключ должен быть уникальным, вы не можете отслеживать два объекта с одним и тем же ключом. Попробуйте сначала отсоединить старый объект:

DatabaseModel db = new DatabaseModel();
var val = db.Members
        .FirstOrDefault(b => b.Name == "Frank");

var val2 = new Player(val);
db.Entry(val).State = EntityState.Detached;
db.Members.Update(val2);

db.SaveChanges();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...