Why can't i use DataAnnotations KeyAttribute for composite keys? - c#

EntityFramework Core restricts using KeyAttribute for defining composite keys.
But what is the reason for this limitation? I have found a solution for this without using Fluent api.

According to this GitHub Issue it is in the backlog to be implemented in the upcoming version of EF Core. And from this GitHub Issue, here is the explanation that you were looking for:
The reason is that it used a combination of Key and Column for ordering, but column ordering is not the same thing as key ordering, and so this caused confusion and issues in EF6. Changing existing data annotations is also costly because of their relationship to .NET Core and .NET Framework.
However, we see the value in being able to this and other common configuration using attributes, since the jump to the fluent API can be a big one. Therefore, we will investigate creating a new library/package with additional new EF configuration attributes that can be used alongside data annotations. This would be one of the things that would be implemented there.
However, According to this announcement, from ASP.NET Core 3.0 you can use all the features of EF 6.x with ASP.NET Core as there will be EF 6.3 on .NET Core >= 3.0

Related

Entity Framework 6 - Database First - String Length Attribute missing

I am using EF6 database first to create my EF 6 DB Context. The POCOs that are created are missing the property attributes such as "StringLength" or "Required". I have been on projects before where these were created for me and thought it was base functionality. Where can I find documentation on how to configure this behavior?
From a new Winform application I added a new ADO.Net Entity Data Model to my project and followed the wizard for "EF Design from database".
Environment
New .Net Framework 4.72 Winform app
EF 6
C#
I found out what happened. By default Scaffold-DBContext's parameter DataAnnotations defaults to use Fluent API. Fluent API configures the properties using function chaining in the OnModelCreating method of the context. The DataAnnotations parameter is a switch, so just specifying the parameter will change the engine to use Data Annotations.
This is important to be because I use the EF Models outside of EF as well. There is a big benefit using them with ASP.net because it will use the annotations during request to validate the models.

Has Microsoft dropped support for database-first?

So I've been programming WebForms and MVC for many years and I'm trying to get up to speed on Razor Pages.
One snag I'm hitting is how to get started with database access (using Entity Framework). In the past, I just created an EDMX file that built classes from my database. And I'm really more comfortable using database-first.
Has anyone seen any official word on forward support for database-first?
If it's not supported, anyone know any good tutorials that are current on setting up a database using code-first?
And if it's not supported, anyone know any good tutorials on porting an existing database over to a code-first project?
As far as I can tell from this article, the EDMX approach relies on a build task that is not (currently) available in .NET Core. However, the article describes this as a "temporary" limitation, suggesting that EF 6 will retain database first when it is fully ported to .NET Core in the shape of EF 6.3.
EF Core does not support the EDMX file format for models. In my opinion, the move to make EF 6 compatible with .NET Core makes it less likely that EF Core will ever support EDMX. But I haven't seen anything official either way.

Where is EnglishPluralizationService in EF Core 2.0?

EF Core 2.0 still has its conventions and it can change plural to singular and singular back to plural. Thus it definitely has the pluralization service built into it.
Yet I can't find this service to use it for other purposes.
In EF 6, I would write:
using System.Data.Entity.Infrastructure.Pluralization;
// Then somewhere in code
var englishPluralizationService = new EnglishPluralizationService();
var singularCat = englishPluralizationService.Singularize("Cats");
EF Core 2.0 still has its conventions and it can change plural to singular and singular back to plural.
Thus it definitely has the pluralization service built into it.
No, it can't do that and has no integrated pluralization service.
As explained in Table Mapping section of the documentation, it uses a simple convention:
By convention, each entity will be setup to map to a table with the same name as the DbSet<TEntity> property that exposes the entity on the derived context. If no DbSet<TEntity> is included for the given entity, the class name is used.
EF Core 2.0 introduced IPluralizer service that is used to singularize entity type names and pluralize DbSet names during scaffolding, but as stated in the link
this is just a hook where folks can easily plug in their own pluralizer
Shorty, there is no such service. For "other needs" you have to use your own or 3rd party pluralizer.
There is no built in pluralization in EF Core, but you can hook in for example the Inflector package: https://www.nuget.org/packages/Inflector/
I do that in "EF Core Power Tools" - see https://github.com/aspnet/EntityFrameworkCore/commit/dda3f43c046c2464f4813fdbb4261a6146aa4432 for more info
#bricelam, a member of the EF Core team, has published this blogpost, where he suggests using his Bricelam.EntityFrameworkCore.Pluralizer package, that is based on the EF Core pluralization service.

How to generate an entity model from a query w/ EntityFrameworkCore

I'm trying to connect an ASP.NET Core web application to an existing, pretty complex database, in read-only mode.
The database is much to complex to map its layout to EFC directly, I just access data from it via a set of queries.
Those queries are well-defined, so I can define objects that match their results in advance without problem.
However, I can't seem to find out how to define the entity model for the database context for this. I can't, of course, set a TableAttribute on the model class - because the model doesn't reflect a table, but simply a query result. Just adding ColumnAttributes to the model's properties doesn't seem to do the trick either, in my OnModelCreating method in the database context, I always get an error "InvalidOperationException: The entity type 'MyEntityModel' requires a key to be defined."
What key am I supposed to define, tho? It's not as if a query has a key for its result entries, or does it/can I make it have one?
Unfortunately, I can't change the database to add new views, temp tables or whatever either, I (can) only have read access.
It might very well be I just haven't understood the concepts behind EF yet, but all tutorials/samples I look at just handle the most basic and simple cases, and my google-fu seems to fail me here as well.
Although it looks like working around the issue using basic connect-query-disconnect w/o EF might be a possibility, it seems to me going the DtabaseContext/EF way is more in line with ASP.NET Core's principles. Feel free to disagree or tell me otherwise if I'm wrong there.
Any samples that might show another way to make this work would be highly appreciated as well.
Okay, I figured it out myself. Seems asking the question helped my google fu. ;)
To anyone else running into the same problem:
My OnModelCreating function now looks like this
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<MyEntityType>(
obj =>
{
obj.Property<int>(nameof(MyEntityType.ArbitraryPropertyIChoseAsId));
obj.HasKey(nameof(MyEntityType.ArbitraryPropertyIChoseAsId));
});
}
…and after a bit of fiddling to get the types of the properties right (who the hell defines a date column as numeric?!) it all works now.
Yes, the properties' types of your Entity type must match the query result, and all query fields must appear as properties, I think.
Of course you should have a "unique" property to serve as your arbitrary Key, but it doesn't have to be a database table key.
This all leads to a slightly ugly entity class; I handled that by making MyEntityType a wrapper class with an implicit conversion operator to the class I'll be using as the data model inside my application (which looks all nice and tidy and has proper types).
Using ASP.NET Core does not mean that you've to use Entity Framework core. You can use Full .NET Framework instead of .NET Core and Entity Framework Full instead of Entity Framework Core. There are several benefits with this:
1- ASP.NET Core 2 (Currently in beta) works well on .NET Standard 2. As both Full .NET Framework 4.6.1+ and .NET Core 2.0+ are implementation of .NET Standard 2.0, you can switch back to .NET Core 2 very easily when its stable release gets published.
2- Entity Framework Core 2.0 (Currently in beta) has a lots of enhancements over Entity Framework Core 1.1.1 . Working with version 2.0 will be far easier than 1.1.1
It has better query translation, better performance, fewer bugs, more methods etc.
So
Step 1 >> Develop app with ASP.NET Core and Full versions of EntityFramework & .NET Framework
Step 2 >> Target .NET Core 2 and Entity Framework Core 2 in your app when they stable releases becomes available.
It's a good idea to use database reverse engineering tool of Entity Framework full, and then change its result to make it compatible with EntityFramework Core.

Can the VS Entity Data Model Designer be configured to use a newer version of the EF?

Can the designer surface in VS2010 be configured for example to use EF 4.3, perhaps?
I think by default it supports 4.0 but what If you use a nuget package to get 4.3? I might be getting my wires crossed with the Code First approach but still I am very happy with the Data Model the designer and have no need to go for a CF approach on this project maybe for future projects.
Is there a default traditional approach i.e if you want to use the designer in vs2010 then you are stuck with EF 4.0, if you want to use the latest and greatest, you have to learn the CF approach?
MSDN - Entity Data Model Designer, .Net 4.0
StackOverFlow similar question
UPDATE:
http://blogs.microsoft.co.il/blogs/gilf/archive/2010/12/08/ef-feature-ctp5-walkthrough-for-the-new-dbcontext-t4-template.aspx
Still could do with some more clarity and an expert oppinion on this.
You can certainly use EF 4.3 with the EF Designer. What this means is using the DbContext API with a Database First or Model First approach, rather than a Code First approach. To do this you need to download the DbContext T4 templates so that the Designer will generate EF 4.3 code instead of EF 4.0 code. This walkthrough was written for EF 4.1 but still applies for 4.3: http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-model-amp-database-first-walkthrough.aspx
Note that using EF 4.3 means using the DbContext APIs. However, this is not the same as using Code First--you can still use the designer with DbContext. That being said, if you want to keep using ObjectContext and not DbContext then there is no value in using 4.3--it doesn't add anything to ObjectContext.
I would stronly encourage people to start using the DbContext APIs regardless of whether they are doing Code First, Database First, or Model First.
To Add to ajcvickers answer, Microsoft recently updated the Code Generator templates, and they now say something like DbContext 4.x POCO Generator or something like that.

Categories