Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does adding a parameterless constructor to my entity model class work here? What are the implications?

So I have this office entity class:

[Table("office_entity")]
public class EFOffice : EFBusinessEntity
{

    [Column("address")]
    [StringLength(250)]
    public string Address { get; set; }

    [Column("business_name")]
    [StringLength(150)]
    public string BusinessName { get; set; }

    public virtual ICollection<EFEmployee> Employees { get; set; }

    public EFOffice(Guid id, Guid tenantId, string address, string businessName)
    {
        this.Id = id;
        this.TenantId = tenantId;
        this.Address = address;
        this.BusinessName = businessName;
    }
}

I'm implementing a generic repository, and I just added this method that checks if an entity already exists in the repository:

public bool Exists<TEntity>(Guid key) where TEntity : class, IBusinessEntity
{
    return (_context.Set<TEntity>().Find(key) != null);
}

Then I wrote the following test code:

public void TestExists1()
{
    InitializeDatabase();
    EFOffice testOffice = InitializeOffice1();
    Debug.Assert(EFRepo.Exists<EFOffice>(testOffice.Id));
}

The method for InitializeOffice1() is as follows:

private EFOffice InitializeOffice1()
{
    EFOffice newOffice = new EFOffice(SparkTest.TestGuid1, SparkTest.TestGuid2, "Generic Address", "HQ");
    return newOffice;
}

The test is supposed to pass because I already inserted the office returned by InitializeOffice1() previously. However, I get the following error:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: The class 'Models.Employees.EF.EFOffice' has no parameterless constructor.

So then I added this to the EFOffice class shown at the top:

private EFOffice()
{

}

And for some reason the test now passes. Can anyone explain what's going on? And does having a parameterless constructor have bad side effects? It's important that every office I insert has an id, a tenantId, an address and a businessName, as listed in the constructor at the top.

like image 431
Drew Avatar asked Jun 16 '15 17:06

Drew


People also ask

What is the use of Parameterless constructor C#?

A constructor that takes no parameters is called a parameterless constructor. Parameterless constructors are invoked whenever an object is instantiated by using the new operator and no arguments are provided to new . For more information, see Instance Constructors.

Do you need a Parameterless constructor?

It is just a requirement for the XML serialization. It is not a requirement per se. Binary formatter for example doesn't need a parameterless constructor, not even a private one.

Does EF core require Parameterless constructor?

Fortunately, while EF does require the parameterless constructor, it need not be public so we can add a private parameterless constructor for EF while forcing calling code to use the parameterised one.

Can structs have Parameterless constructor?

A parameterless instance constructor is valid for all struct kinds including struct , readonly struct , ref struct , and record struct .


1 Answers

All Entities linked to EntityFramework must have a Default Constructor.

When Entity Framework maps from a database query to your Entities use the default constructor to instantiate a new instance of your Entity to fill it with the data retrieved from your database.

If you don't have a default constructor Entity Framework doesn't know how to create an instance of it and throws the exception

The class 'Models.Employees.EF.EFOffice' has no parameterless constructor.

like image 120
Marc Cals Avatar answered Oct 19 '22 11:10

Marc Cals