2014-02-12 4 views
2

Я заметил довольно странное поведение с тем, как Entity Framework создает код-первый DB, когда у вас есть модель с родителем, у которого есть список детей, необязательное свойство навигации для одного конкретного дочернего элемента: в итоге у меня есть дополнительный столбец с нулевым внешним ключом для дочернего элемента, которого я не ожидаю. Может ли кто-нибудь объяснить, нужна ли эта колонка? И в этом отношении кто-нибудь может предложить лучший способ указать, что конкретный ребенок выбран/активен.Entity Framework с дополнительным дочерним навигационным свойством создает дополнительные столбцы

Выработать:

Учитывая эту модель:

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

    public virtual List<Child> Children { get; set; } 

    // Optional navigation property to one of the child objects. 
    public int? ActiveChildId { get; set; } 
    public virtual Child ActiveChild { get; set; } 
} 

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

    public int ParentId { get; set; } 
    public virtual Parent Parent { get; set; } 
} 

я в конечном итоге со следующей БД:

CREATE TABLE [dbo].[Parents](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [ActiveChildId] [int] NULL, 
CONSTRAINT [PK_dbo.Parents] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[Parents] WITH CHECK ADD CONSTRAINT [FK_dbo.Parents_dbo.Children_ActiveChildId] FOREIGN KEY([ActiveChildId]) 
REFERENCES [dbo].[Children] ([Id]) 
GO 

ALTER TABLE [dbo].[Parents] CHECK CONSTRAINT [FK_dbo.Parents_dbo.Children_ActiveChildId] 
GO 

CREATE TABLE [dbo].[Children](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [ParentId] [int] NOT NULL, 
    [Parent_Id] [int] NULL, 
CONSTRAINT [PK_dbo.Children] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[Children] WITH CHECK ADD CONSTRAINT [FK_dbo.Children_dbo.Parents_Parent_Id] FOREIGN KEY([Parent_Id]) 
REFERENCES [dbo].[Parents] ([Id]) 
GO 

ALTER TABLE [dbo].[Children] CHECK CONSTRAINT [FK_dbo.Children_dbo.Parents_Parent_Id] 
GO 

ALTER TABLE [dbo].[Children] WITH CHECK ADD CONSTRAINT [FK_dbo.Children_dbo.Parents_ParentId] FOREIGN KEY([ParentId]) 
REFERENCES [dbo].[Parents] ([Id]) 
GO 

ALTER TABLE [dbo].[Children] CHECK CONSTRAINT [FK_dbo.Children_dbo.Parents_ParentId] 
GO 

т.е. есть как ParentId (NOT NULL) столбец дочерний элемент и столбец Parent_Id (NULL) для дочернего элемента.

Мне кажется, что поскольку у нас уже есть отношения с внешним ключом 1: N с родительским с ребенком, то добавив одностороннюю связь 1: [0 или 1] от родителя к ребенку, он не должен создавать другой столбец внешнего ключа для ребенка.

ответ

4

Добавить InverseProperty атрибут:

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

    public int ParentId { get; set; } 

    [InverseProperty("Children")] 
    public virtual Parent Parent { get; set; } 
} 

Или карта отношений с помощью Fluent API и указать FK, как ParentId:

 modelBuilder.Entity<Parent>() 
      .HasMany(p => p.Children) 
      .WithRequired(c => c.Parent) 
      .HasForeignKey(c => c.ParentId); 
+0

К сожалению, я не верю, что любой из этих предложений поможет. Если я допустил, что значение параметра ParentId недействительно, оно больше не подходит для моего отношения 1: N, а Entity Framework уже вводит ParentId в качестве внешнего ключа для родителя на основе соглашения об именах. – Clint

+0

Он работает, я тестировал его – Moho

+0

добавить 'RequiredAttribute' в свойство, если вы не хотите, чтобы nullable' ParentId' – Moho

Смежные вопросы