Eu tenho 3 models: Caixa, CaixaMovimento e SolicitacaoRecurso.
Há vários caixas e cada um tem seus Movimentos e suas Solicitações de Recursos. Um caixa terá muitos movimentos e solicitações mas um Movimento será só de um caixa , da mesma forma acontecendo com as Solicitações.
public class Caixa
{
public Caixa ()
{
SolicitacoesRecurso = new List<SolicitacaoRecurso>();
Movimentos = new List<CaixaMovimento >();
}
[Key]
public int ID { get; set; }
[Required, StringLength(30)]
public string Nome { get; set; }
[Required, StringLength(128)]
public string ApplicationUserId { get; set; }
public ApplicationUser Responsavel { get; set; }
[Required, DataType(DataType.Currency)]
public decimal SaldoInicial { get; set; }
[Required, DataType(DataType.Currency)]
public decimal SaldoAtual { get; set; }
public virtual IList<CaixaMovimento> Movimentos { get; set; }
public virtual IList<SolicitacaoRecurso> SolicitacoesRecurso { get; set; }
}
public class CaixaMovimento
{
public CaixaMovimento()
{
Caixas = new List<Caixa>();
}
[Key]
public int ID { get; set; }
[Required, DataType(DataType.Date)]
public DateTime Data { get; set; }
[Required, StringLength(200)]
public string Historico { get; set; }
[Required, DataType(DataType.Currency)]
public decimal Valor { get; set; }
[Required]
public virtual MovimentacaoEnum Movimentacao { get; set; }
public virtual IList<Caixa> Caixas { get; set; }
}
public class SolicitacaoRecurso
{
[Key]
public int ID { get; set; }
[Required, DataType(DataType.Date)]
public DateTime Data { get; set; }
[Required, StringLength(128)]
public string ApplicationUserId { get; set; }
public ApplicationUser Usuario { get; set; }
[Required]
public int CaixaID { get; set; }
public virtual Caixa Caixa { get; set; }
[Required, DataType(DataType.Currency)]
public decimal Valor { get; set; }
[Required]
public string Motivo { get; set; }
public bool Entregue { get; set; }
}
Quando fiz o update-database, o EF criou uma tabela para os Caixas, uma para CaixaMovimentos, outra para SolicitacoesRecurso e criou também uma tabela que ele nomeou de CaixaCaixaMovimentos que relaciona ID de caixa com ID de CaixaMovimento.E só. Não criou a mesma coisa para Caixas com SolicitacoesRecurso.
Criei caixas sem problemas.
Criei Movimentos sem problemas. Mas eles não se ligam com o Caixa na tal tabela relacional CaixaCaixaMovimento.
Não ficou claro como relacionar Caixas com Movimentos. Pelo visto vou ter de pegar os dois IDs e inserir nessa tabela CaixaCaixaMovimentos. O sistema não faz sozinho já que ele é que entender que havia essa necessidade de relacionar?
E também não ficou claro como vão ser preenchidas aquelas listas que são criadas nos models. A classe Caixa tem uma lista de CaixaMovimento.
Cada vez que cadastro um CaixaMovimento tenho que adicionar ele na lista? Ou tenho que relacionar ele com o Caixa através daquela tabela de relacionamento?
E as Solicitações de Recurso? Tenho que ao criar uma nova SolciitacaoRecurso adicionar ela na lista do Caixa?
Na tabela Caixa há um campo SaldoAtual que eu pretendia que fosse atualizado toda vez que um movimento for adicionado ao Caixa. Então fiz um método no DAO que soma esses movimentos e edita a coluna SaldoAtual do Caixa. O problema é que quando vou gravar essa edição ele reclama uma exceção lançada justamente pela lista de SolicitacoesRecurso (que está vazia) que nada tem a ver com isso.
Com se não pudesse Salvar a edição por que a lista de SolicitacoesRecurso não existe (está vazia) para quele caixa.
Vou colocar abaixo a estrutura das tabelas:
CREATE TABLE [dbo].[Caixas] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[Nome] NVARCHAR (30) NOT NULL,
[SaldoInicial] DECIMAL (18, 2) NOT NULL,
[SaldoAtual] DECIMAL (18, 2) NOT NULL,
[ApplicationUserId] NVARCHAR (128) NOT NULL,
CONSTRAINT [PK_dbo.Caixas] PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [FK_dbo.Caixas_dbo.AspNetUsers_ApplicationUserId] FOREIGN KEY ([ApplicationUserId]) REFERENCES [dbo].[AspNetUsers] ([Id])
);
GO
CREATE NONCLUSTERED INDEX [IX_ApplicationUserId]
ON [dbo].[Caixas]([ApplicationUserId] ASC);
CREATE TABLE [dbo].[CaixaMovimentos] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[Data] DATETIME NOT NULL,
[Historico] NVARCHAR (200) NOT NULL,
[Valor] DECIMAL (18, 2) NOT NULL,
[Movimentacao] INT NOT NULL,
[ApplicationUserId] NVARCHAR (128) NOT NULL,
CONSTRAINT [PK_dbo.CaixaMovimentos] PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [FK_dbo.CaixaMovimentos_dbo.AspNetUsers_ApplicationUserId] FOREIGN KEY ([ApplicationUserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_ApplicationUserId]
ON [dbo].[CaixaMovimentos]([ApplicationUserId] ASC);
CREATE TABLE [dbo].[SolicitacaoRecursos] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[Data] DATETIME NOT NULL,
[CaixaID] INT NOT NULL,
[Valor] DECIMAL (18, 2) NOT NULL,
[Motivo] NVARCHAR (MAX) NOT NULL,
[Entregue] BIT NOT NULL,
[ApplicationUserId] NVARCHAR (128) NOT NULL,
CONSTRAINT [PK_dbo.SolicitacaoRecursos] PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [FK_dbo.SolicitacaoRecursos_dbo.Caixas_CaixaID] FOREIGN KEY ([CaixaID]) REFERENCES [dbo].[Caixas] ([ID]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.SolicitacaoRecursos_dbo.AspNetUsers_Usuario_Id] FOREIGN KEY ([ApplicationUserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_CaixaID]
ON [dbo].[SolicitacaoRecursos]([CaixaID] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_ApplicationUserId]
ON [dbo].[SolicitacaoRecursos]([ApplicationUserId] ASC);
CREATE TABLE [dbo].[CaixaCaixaMovimentos] (
[Caixa_ID] INT NOT NULL,
[CaixaMovimento_ID] INT NOT NULL,
CONSTRAINT [PK_dbo.CaixaCaixaMovimentos] PRIMARY KEY CLUSTERED ([Caixa_ID] ASC, [CaixaMovimento_ID] ASC),
CONSTRAINT [FK_dbo.CaixaCaixaMovimentos_dbo.Caixas_Caixa_ID] FOREIGN KEY ([Caixa_ID]) REFERENCES [dbo].[Caixas] ([ID]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.CaixaCaixaMovimentos_dbo.CaixaMovimentos_CaixaMovimento_ID] FOREIGN KEY ([CaixaMovimento_ID]) REFERENCES [dbo].[CaixaMovimentos] ([ID]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_Caixa_ID]
ON [dbo].[CaixaCaixaMovimentoes]([Caixa_ID] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_CaixaMovimento_ID]
ON [dbo].[CaixaCaixaMovimentoes]([CaixaMovimento_ID] ASC);