Сначала код EF - наследование и отношения - PullRequest
1 голос
/ 13 марта 2012

Пожалуйста, посмотрите на следующий код:

public class SomeEntity
{
    public int Id { get; set; }

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

public class SomeEntityA : SomeEntity
{
    public int Number { get; set; }
}

public class SomeEntityB : SomeEntity
{
    public string Text { get; set; }
}

public class User
{
    public int Id { get; set; }
    public int Username { get; set; }

    public virtual ICollection<SomeEntityA> SomeEntitiesA { get; set; }
    public virtual ICollection<SomeEntityB> SomeEntitiesB { get; set; }
}

У меня вопрос: есть ли способ настроить FluentApi, чтобы показанные выше отношения работали правильно? В настоящее время, когда новый объект SomeEntityA добавляется в User, EF создает новую запись в таблице SomeEntities с правильно установленной FK User_Id, однако в SomeEntitesA, которая является унаследованной таблицей, есть также свойство FK User_Id - устанавливается как null, и когда я пытаюсь получить SomeEntitesA коллекция из объекта User - она ​​пустая. Я понимаю, почему это происходит, но я не уверен, есть ли способ это исправить? Единственное решение, которое приходит мне в голову на данный момент, это заменить следующий код:

    public virtual ICollection<SomeEntityA> SomeEntitiesA { get; set; }
    public virtual ICollection<SomeEntityB> SomeEntitiesB { get; set; }

с:

    public virtual ICollection<SomeEntity> SomeEntitiesA { get; set; }
    public virtual ICollection<SomeEntity> SomeEntitiesB { get; set; }

и настройте FluentApi.

Любые мысли будут высоко оценены.

Ответы [ 2 ]

1 голос
/ 13 марта 2012

Посмотрите на этот вопрос / ответ, классы имеют точно такую ​​же структуру, как у вас, и есть подробное объяснение, почему все работает не так, как ожидалось:

Поддерживается ли наследование свойств навигации?

Как указал Слаума, существует довольно простое решение, позволяющее обойти это, выполнив следующее (скопировано из связанного ответа и соответствует вашему примеру):

public class User
{
    public int Id { get; set; }
    public int Username { get; set; }

    // this is necessary to have access to the related SomeEntityAs/SomeEntityBs
    // also it cant be private otherwise EF will not overload it properly
    public virtual ICollection<SomeEntity> SomeEntities { get; set; }

    public IEnumerable<SomeEntityA> SomeEntitiesA { get { return this.SomeEntities.OfType<SomeEntityA>(); } }
    public IEnumerable<SomeEntityB> SomeEntitiesB { get { return this.SomeEntities.OfType<SomeEntityA>(); } }
}
1 голос
/ 13 марта 2012

Предлагаемое вами решение также не будет работать, поскольку вы не можете связать два навигационных свойства User.SomeEntitiesA и User.SomeEntitiesB с одной и той же конечной точкой SomeEntity.User. На самом деле вам понадобится два пользователя:

public class SomeEntity
{
    public int Id { get; set; }

    public int UserAId { get; set; }
    [InverseProperty("SomeEntitiesA")]
    public virtual User UserA { get; set; }

    public int UserBId { get; set; }
    [InverseProperty("SomeEntitiesB")]
    public virtual User UserB { get; set; }
}

Но тогда вы также можете оставить типы коллекций такими, какие они есть, и переместить пользователей в производные объекты:

public class SomeEntity
{
    public int Id { get; set; }
}

public class SomeEntityA : SomeEntity
{
    public int Number { get; set; }

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

public class SomeEntityB : SomeEntity
{
    public string Text { get; set; }

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

public class User
{
    public int Id { get; set; }
    public int Username { get; set; }

    public virtual ICollection<SomeEntityA> SomeEntitiesA { get; set; }
    public virtual ICollection<SomeEntityB> SomeEntitiesB { get; set; }
}

В этом случае вам не нужно указывать [InverseProperty], так как соглашения теперь будут определять правильные пары навигационных свойств.

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