Reputation: 10444
I have a project with a small data model that consumes EF models in a read-only fashion.
I don't want the full set of columns in the models, but I am required to have them if they are non-nullable and have no default values.
How can I avoid including such columns? Can I put EF into some read-only mode in the data model which will allow me to remove the columns from the entities?
The reason I want to do this is because by reducing the columns in my data models only to what I need I reduce the columns the model needs to return in queries and I reduce the risk of breaking my data consumers if the schema changes.
EDIT: My schema has tables with NOT NULL
columns having no default values. As far as I can tell I am required to have these columns included in my edmx. In my situation I only have read-only context so I don't want these columns to be included in my edmx at all.
If I can prevent the columns from being in the data model I can prevent many issues arising from changing the schema. The only solution I've found so far is to build the datamodel by pointing to a "fake" database which doesn't have the columns!
Upvotes: 11
Views: 1591
Reputation: 1692
According to MSDN, a QueryView is designed for exactly the scenario you describe.
The QueryView element in mapping specification language (MSL) defines a read-only mapping between an entity type or association in the conceptual model and a table in the underlying database.
You can define query views to enable the following scenarios:
Define an entity in the conceptual model that doesn't include all the properties of the entity in the storage model. This includes properties that do not have default values and do not support null values.
...(more scenarios on the page)
You can't use the designer for this, but it looks simple enough to do by hand.
Here is a link to the relevant MSDN documentation:
https://msdn.microsoft.com/en-us/library/cc716798(v=vs.100).aspx
In case that link goes dead, do a search for QueryView MSL
.
Upvotes: 4
Reputation: 401
You can also resolve this issue by removing the unwanted properties from the edmx storage model section.
Upvotes: 0
Reputation: 31616
I can prevent many issues arising from changing the schema.
That falls back ultimately to database design. The database needs to be designed differently for the upgrade scenario you present. By moving out the said columns to a nullable FK related table would be a viable option with no future changes needed for EF.
but I am required to have them if they are non-nullable and have no default values.
EF only dutifully reports what is in the database as by its design.
Any schema change could affect a number of factors such as new constraints, triggers and overall table changes. Hiding columns in a designer and then hoping it works on a different schema-d database is not wise.
I have personally run into out of sync EF design models and there are logical errors that can effect the code in strange ways.
I reduce the risk of breaking my data consumers if the schema changes.
Exactly how are these consumers accessing the data?
Any true consumer should go through either a webservice or factory pattern access layer where the data should only be returned as Interface
type data object(s). Therefore when/if database or schema changes, the interface(s) returned do/does not change; hence that schema update does not break any consumer safe behind an interface regardless of the concrete object being used.
It is not the answer you want, but this provides two alternatives to achieving the same goal.
Upvotes: 3
Reputation: 109099
If you're willing to use code-first in stead of database-first this could be really simple.
Take for instance Microsoft's sample database School
. It has a table Course
with a number of required fields. But it's possible to map a class with only a small subset of these fields...
class Course
{
public int CourseID { get; private set; }
public string Title { get; private set; }
}
...to this table, ignoring required fields Credits
and DepartmentID
.
The fluent mapping in the context's OnModelCreating
override is
modelBuilder.Entity<Course>().HasKey(a => a.CourseID);
modelBuilder.Entity<Course>().Property(a => a.CourseID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
As you see, I defined the properties with a private setter. EF has no problems with that and it communicates to any consumer of the model that the model is read-only.
On top of this you could even map non-key properties as Computed
:
modelBuilder.Entity<Course>().Property(a => a.Title)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
Now it's impossible to update any property value inadvertently, because EF simply won't include them in UPDATE
statements.
Upvotes: 3
Reputation: 2972
Are you looking for data annotation [NotMapped]
?
If you use it in a property inside model, it will not pass to the db.
Upvotes: 3