deevodavis
deevodavis

Reputation: 131

Using a View with Entity Framework 5 Code First

I have created a SQL Server view which performs some reasonably complex logic on other tables/entities in my model and which exposes a series of columns. All but one of these columns are simple types (bigints, nvarchars etc) but one is a complex entity within my model.

I have created an entity which maps to this view as follows:

public class NetworkSuppliersByClient : Entity, IKeyed<long>
{
    public long NetworkSuppliersByClientId { get; set; }

    public long NetworkId { get; set; }
    public String NetworkName { get; set; }
    public long OwningClientId { get; set; }
    public long ClientId { get; set; }
    public virtual Supplier Supplier { get; set; }
    public bool PublicEntry { get; set; }

    public long GetKey ()
    {
        return NetworkSuppliersByClientId;
    }
}

As you can see, the Supplier entry maps to an existing entity within the model, itself being a complex type with other contained entities (aka tables).

The issue that I have is that when I try to read from the view I get the error "The entity type NetworkSuppliersByClient is not part of the model for the current context.".

However, when I try to register the entity with the context as a DbSet I get the error "There is already an object named 'NetworkSuppliersByClients' in the database." as it tries to create a table with the same name as the already existing view.

Is there any way around this, for example to inhibit EF from trying to create the table at startup, or is there a better way to read from a view?

Upvotes: 2

Views: 2352

Answers (1)

deevodavis
deevodavis

Reputation: 131

To anyone else who's interested I ended up just side-stepping the issue.

I mapped the entity NetworkSuppliersByClient (shown above) instead directly to the response from the view response, with the exception that I gave up trying to return the Supplier entity as an embedded entity instead returning it as a primitive long.

public class NetworkSuppliersByClient : Entity, IKeyed<long>
{
    public long NetworkSuppliersByClientId { get; set; }

    public long NetworkId { get; set; }
    public String NetworkName { get; set; }
    public long OwningClientId { get; set; }
    public long ClientId { get; set; }
    public long SupplierId { get; set; }    <-- Long, rather than "Supplier"
    public bool PublicEntry { get; set; }

    public long GetKey ()
    {
        return NetworkSuppliersByClientId;
    }
} 

Once I had the list of Supplier IDs as longs I then performed a subsequent Entity Framework query (using the .Contains() method) to return all of the suppliers as real EF entities.

The key is that the entity (NetworkSuppliersByClient in my case above) shouldn't exist as a declared DbSet member within the DbContext subclass, or indeed referenced by any entities already in an existing DbSet<>. If you enforce this rule then Entity Framework won't try to create the table at startup and it shouldn't cause any conflicts with the already existing view.

Upvotes: 1

Related Questions