Save record in bank with entity

1

Dear colleagues.

I'm developing a C# Winform application with database SqlServer and Entity framework . As I am inexperienced, I have been learning through the internet. I'm having a hard time understanding and implementing some concepts regarding object orientation in relation to database manipulation.

I'll put down parts of my system to see if they can help me make this code functional. To be more objective, my code until it was working but without the proper relationships between the tables. When I modified it so the tables had relationships it started giving errors, as this follows.

Thanks for the help.

  

System.Data.Entity.Infrastructure.DbUpdateException     HResult = 0x80131501     Message = Entities in 'BancoContexto.PedidoCtx' participate in the 'Client_PedidoPrincipalX' relationship. 0 related   'Client_PedidPrincipalX_Source' were found. 1 'Client_PedidPrincipalX_Source' is expected.

namespace DAL.MODEL
{
    public class Cliente
    {
        public Cliente()
        {
            this.PedidoPrincipalX = new List<PedidoPrincipal>();
        }

        public int ClienteId { get; set; }
        public string Nome { get; set; }

        public virtual ICollection<PedidoPrincipal> PedidoPrincipalX { get; set; }
    }
}

namespace DAL.MODEL
{
    public class PedidoPrincipal
    {
        public int PedidoId { get; set; }
        public DateTime DataEmissao { get; set; }
        public Decimal Total { get; set; }

        public int FK_ClienteId { get; set; }
        public virtual Cliente ClienteX { get; set; }
    }
}

namespace DAL.MAPPING
{
    public class ClienteMap : EntityTypeConfiguration<Cliente>
    {
        public ClienteMap()
        {
            ToTable("Cliente");
            HasKey(c => c.ClienteId);
            Property(c => c.ClienteId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            HasMany(X => X.PedidoPrincipalX);
        }
    }
}


namespace DAL.MAPPING
{
    public class PedidoPrincipalMap : EntityTypeConfiguration<PedidoPrincipal>
    {
        public PedidoPrincipalMap()
        {
            ToTable("PedidoPrincipal");
            HasKey(p => p.PedidoId);
            Property(p => p.PedidoId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            HasRequired(X => X.ClienteX);
        }
    }
}

Excerpt of code to save to bank:

private void btnSalvar_Click(object sender, EventArgs e)
{
    PedidoPrincipalRepositorio app = new PedidoPrincipalRepositorio();

    PedidoPrincipal pedido = new PedidoPrincipal();

    pedido.FK_ClienteId = Int32.Parse(txtCodigoCli.Text);

    pedido.DataEmissao = DateTime.Now;
    pedido.Total = decimal.Parse(txtValorTotal.Text);

    app.Adicionar(pedido);
    app.SalvarTodos();
}
    
asked by anonymous 30.04.2018 / 21:21

1 answer

1

We'll first make some changes to your Model to make your life easier, we'll use conventions / a> Code First .

namespace DAL.MODEL{

    public class Cliente
    {
        public Cliente()
        {
            this.PedidoPrincipalX = new List<PedidoPrincipal>();
        }

        public int Id { get; set; }
        public string Nome { get; set; }

        public virtual ICollection<PedidoPrincipal> PedidoPrincipalX { get; set;} 
    }
}

Modifications

  • Replaces public int ClienteId { get; set; } with public int Id { get; set; } , in this way we begin to use EF conversion, so he understands that ID is the primary key of the Client , and will use the same key as FK , in your relationships
namespace DAL.MODEL
{
    public class PedidoPrincipal
    {
        public int Id { get; set; }
        public DateTime DataEmissao { get; set; }
        public Decimal Total { get; set; }
        public int ClienteId {get;set;}

        public virtual Cliente ClienteX { get; set; }
    }
}

Modifications:

  • Replace public int PedidoId { get; set; } with public int Id {get; set; } ', at least from above, to maintain the convention, thus simply using the virtual properties, will cause EF to understand the relationship automatically

  • Removing% with%, because by adopting EF conventions, this property becomes unnecessary, and may even disrupt EF p>

  • Include public int FK_ClienteId { get; set; } , replacing the removed property, so you can use it to connect the client to the request. Note: You should follow the writing pattern, {class name + Id}, so EF will identify those properties as public int ClienteId {get;set;} .

Well, now that we've solved the model, let's go to Mappings:

namespace DAL.MAPPING{

    public class ClienteMap : EntityTypeConfiguration<Cliente>
    {
        public ClienteMap(){
            Property(c => c.ClienteId)
              .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        }
    }
}


namespace DAL.MAPPING
{
    public class PedidoPrincipalMap : EntityTypeConfiguration<PedidoPrincipal>{
        public PedidoPrincipalMap()
        {
            Property(p => p.PedidoId)                   
               .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        }
    }
 }

Modifications:

  • We only left the FK setting, because as I said above, using the EF conventions, the whole relationship part is already created automatically, so this configuration becomes unnecessary for Fluent Api .

In this way your code stays clean, easy to understand, and lessens these chances of relationship errors. The link I went through on the conventions also has several tutorials on things you will need, I think it is a good one, it will help you a lot in the beginning, it was what I used as a study source to learn.

    
01.05.2018 / 00:17