What are the errors in this code using EF6?

Asked

Viewed 32 times

1

What are the errors or inappropriate practices in this code?

static void Main(string[] args)
{
    using (var db = new AccountingSystemContainer())
    {
        var invHeader = db.InvoiceHeaderSet.Create();
        var invDetail = db.InvoiceDetailSet.Create();

        invHeader.Total = 150m;

        invDetail.ItemDescription = "Algum Item";
        invDetail.Price = 75m;
        invDetail.Quantity = 2;

        invHeader.InvoiceDetail.Add(invDetail);

        db.InvoiceHeaderSet.Add(invHeader);
        db.SaveChanges();
    }
}

public partial class InvoiceDetail
{
    public int InvoiceDetail_Id { get; set; }
    public string ItemDescription { get; set; }
    public int Quantity { get; set; }
    public decimal Price { get; set; }
    public int InvoiceHeaderInvoiceHeader_Id { get; set; }

    public virtual InvoiceHeader InvoiceHeader { get; set; }
}

public partial class InvoiceHeader
{
    public InvoiceHeader()
    {
        this.InvoiceDetail = new HashSet<InvoiceDetail>();
    }

    public int InvoiceHeader_Id { get; set; }
    public decimal Total { get; set; }

    public virtual ICollection<InvoiceDetail> InvoiceDetail { get; set; }
}

public partial class AccountingSystemContainer : DbContext
{
    public AccountingSystemContainer()
        : base("name=AccountingSystemContainer")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<InvoiceHeader> InvoiceHeaderSet { get; set; }
    public virtual DbSet<InvoiceDetail> InvoiceDetailSet { get; set; }
}

1 answer

2


1. Nomenclature of Keys

Names used for primary keys are outside the standard Entity Framework Ids search convention. The right thing would be:

public partial class InvoiceDetail
{
    public int InvoiceDetailId { get; set; }
    ...
}

public partial class InvoiceHeader
{
    public int InvoiceHeaderId { get; set; }
    ...
}

Or else:

public partial class InvoiceDetail
{
    public int Id { get; set; }
    ...
}

public partial class InvoiceHeader
{
    public int Id { get; set; }
    ...
}

Or even, if the bank already exists and you want to use the names that are outside the convention, you can use it like this:

[Table("INVOICE_DETAIL")]
public partial class InvoiceDetail
{
    [Key]
    [Column("InvoiceDetail_Id")]
    public int InvoiceDetail_Id { get; set; }
    ...
}

[Table("INVOICE_HEADER")]
public partial class InvoiceHeader
{
    [Key]
    [Column("InvoiceHeader_Id")]
    public int InvoiceHeader_Id { get; set; }
    ...
}

2. Initializing Navigation Properties in the Constructor

The Entity Framework initializes the navigation properties on its own. You don’t need to initialize anything, because this effort is useless. Entity Framework will reassign navigation properties when it deems it necessary:

public partial class InvoiceHeader
{
    // Retire
    /* public InvoiceHeader()
    {
        this.InvoiceDetail = new HashSet<InvoiceDetail>();
    } */
    ...
}

3. UnintentionalCodeFirstException in OnModelCreating

Here is not quite an error: it is an observation. The code below prevents you from making any structural changes in bank:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}

Since you may be using Model/Database First to map a database that already exists, it is pertinent to keep the annotation only to ensure that the Entity Framework will not make any changes to the database.

However, it is important to say that if the database is not identical to Models mapped in your application, the chance of error is quite large.

4. Other details

These are not errors. They are observations that may be relevant to your development.

It’s unclear to me why the nomenclature of a data context like AccountingSystemContainer. It does not make it clear to the programmer that it is a DbContext.

The DbSetjust don’t need to have Set at the end. If they are properties that belong to the context, most likely they will be DbSets (with some exceptions, such as Database).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.