dotnet / ef6

This is the codebase for Entity Framework 6 (previously maintained at https://entityframework.codeplex.com). Entity Framework Core is maintained at https://github.com/dotnet/efcore.
https://docs.microsoft.com/ef/ef6
MIT License
1.43k stars 545 forks source link

Can't map two classes with same name from different namespace #362

Closed saeb-panahifar closed 7 years ago

saeb-panahifar commented 7 years ago

We have an enterprise web application, we have a bug about mapping in DbContext EntityFramework 6.0.0.

"Can't map two classes with the same name from different namespaces"

System.NotSupportedException: 'The type 'Pajoohesh.System.Inf.Domain.TypesEntity' and the type 'Pajoohesh.Eng.Que.Domain.TypesEntity' both have the same simple name of 'TypesEntity' and so cannot be used in the same model. All types in a given model must have unique simple names. Use 'NotMappedAttribute' or call Ignore in the Code First fluent API to explicitly exclude a property or type from the model.'

why?

ajcvickers commented 7 years ago

This is a duplicate of an issue on the old CodePlex site: https://entityframework.codeplex.com/workitem/483. I have copied the thread here since CodePlex is shutting down. In particular, note:

The EDMX needs to be edited manually to add the annotations since the tools won't add them. For a simple model with a Person entity, the ConceptualModels section of the EDMX would look like this:

<ConceptualModels>
    <Schema Namespace="ConsoleApplication33" 
        Alias="Self" 
        annotation:UseStrongSpatialTypes="false"
        xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" 
        xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" 
        xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
    <EntityType Name="Person" 
        customannotation:ClrType="MyApp.Person, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <Key>
        <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
        <Property Name="Name" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" />
    </EntityType>
    <EntityContainer Name="Town" customannotation:UseClrTypes="true">
        <EntitySet Name="People" EntityType="Self.Person" />
    </EntityContainer>
    </Schema>
</ConceptualModels>

Notice in particular the customannotation:ClrType on the Person entity type and the customannotation:UseClrTypes on the entity container.


Full CodePlex thread

aszora wrote Sep 12, 2012 at 2:36 AM

The problem with EF codefirst that it uses a flat namespace internally.

For examaple if you have a Question class which has an Answer navigation property the internal modelmetada will contain a reference called QUESTION_ANSWER.

So if occasionally you have a view in the database named QUESTION_ANSWER, you cant use it, because of duplicate name:) (I did this when I tried to specify a view for many-to-many rel for example.)

mousedoc wrote Sep 12, 2012 at 6:51 AM

Yes, but that is a significant problem with EF. It will allow the following to compile for the above.

public class MyTextContext : DbContext
{
    public DbSet<Test.Security.Question> Security_Question { get; set; }
    public DbSet<Test.Forms.Question> Forms_Question { get; set; }
}

Took me a long time to track it down because the error message was something like "Question not mapped". When I would at the data annotations on classes and the fluent API it was clear I had things configured properly.

RoMiller wrote Oct 16, 2012 at 11:08 AM

Updating title and description to reflect that this is a general EF issue and not specific to Code First.

This is a limitation of EF that we plan to fix but it is complicated and not something we are planning to address in EF6. Marking to be fixed in a future release. glide wrote Nov 21, 2012 at 10:05 AM

Just ran into this problem when trying to create entities that are separated by schema in the database and using custom T4 templates to generate the entities into different namespaces.

moozzyk wrote Jan 6, 2013 at 5:44 PM

Adding exception message to make it easier to find:

The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type 'ABC'. Previously found CLR type 'Ns1.ABC', newly found CLR type 'Ns2.ABC."}

ajcvickers wrote Mar 1, 2013 at 3:58 PM

This now works for EF6 but only when using Code First See: http://entityframework.codeplex.com/workitem/911

This item remains open and in futures for Database First and Model First.

RoMiller wrote Mar 8, 2013 at 11:11 AM

To add to what Arthur said - we've fixed (for Code First only) the issue that prevented you having a Question class in your model and then another Question class that isn't in your model and lived in a different namespace. In EF6 we have not enabled having two Question classes included in your model.

mousedoc wrote Mar 8, 2013 at 12:03 PM

Both were in my model, so this doesn't help my situation. I could have just applied an Ignore attribute to the class if I wanted this fix.

guru_fordy wrote Oct 31, 2013 at 9:05 AM

Just ran into this for the first time on EF 6.01 using DB First. To say I was disappointed that it was only fixed in CF was an understatement. I am at the end of a SOA proof of concept and putting two service calls through to two separate EDM's with one shared table breaks the code. Both EDM's separated by assembly and namespace, but that obviously means nothing to EF.

Is there an ETA on a fix to this or should I be looking at other ORM's that can handle my situation?

sanilpaul wrote Nov 11, 2013 at 8:11 AM

Is there an ETA to fix this? Just as the previous comments, we are building software based on SOA. Each boundary has its on schema. Order in Sales have a different meaning as Order in Inventory. Now we are forced to pollute the code base due to EF restrictions by having a name different than the ubiquitous naming in each context. Very painful

Powdor wrote Feb 5, 2014 at 5:48 AM

We are providing data services based on EF where we need versioning. So new versions are put in seperate namespaces (not changing the class name). this caused the same issue. Now we need to pollute old versoins with a postfix to work arround the issue.

It would be great if it would simply take the namespace into account.

cragun wrote Feb 5, 2014 at 7:23 AM

I would like to up vote the priority of this fix as well. Needs to get fixed asap. Modern programming languages have namespaces and EF needs to respect this. As many have said, the only work around is seriously polluting your Models with less than ideal naming conventions.

tonyatl wrote May 26, 2014 at 6:43 AM

cragun's comments are exactly my own and far more restrained. that this defect is considered low impact is nonsense - it makes using ef like shopping for tourist novelties in a tacky airport gift shop.

UberError wrote Aug 13, 2014 at 6:13 AM

I agree with the above posts. This issue should take priority as it promotes bad naming conventions in SQL to accommodate an oversight in EF.

Godrules500 wrote Aug 22, 2014 at 1:33 PM

I agree. I have several applications, each which has its own schema, that I would like to import into the EF. Now I'm going to have to separate my EDMX files instead of having 1, or create an extremely ugly naming convention in the db.

Is there any update on this issue being fixed?

tboring wrote Oct 6, 2014 at 11:01 PM

I just ran into this issue for the first time--using EF 5. Funny thing is, this issue hasn't been happening until now, and my code's been in PROD for 6 months. We recently enhanced the database, adding 14 new tables. We then added the new entities and classes, and now two of the entities/tables that have the same name, but are in different DB schema and namespaces are, I presume, conflicting.

RichardPawson wrote Oct 7, 2014 at 3:59 AM

Rowan - please tell us if this issue is going to be fixed in EF 7. It is a major limitation if you are building large scale enterprise systems (as we are and many others in the above comments, clearly).

More generally, now that the code base & issues list has shifted to GitHub - is anyone paying attention to issues on CodePlex now. This one has 87 votes, but I can't find any equivalent on the GitHub issues list.

jplonghi wrote Mar 12, 2015 at 9:21 PM

Any update on this?

HansTsai wrote Apr 1, 2015 at 7:32 PM

Hello, Is any update for this issue??

It bothered me for a long time.

dellycowboy wrote May 12, 2015 at 10:03 AM

Honestly, I find this gobsmacking that the team feel that this is given so little priority, really not acceptable. That's all I have to say.

scaredoftheclaw wrote Jul 21, 2015 at 9:55 PM

I just came across this one. Thanks a lot Microsoft.

IoanHancu wrote Jul 28, 2015 at 11:12 AM

it was mentionned here : https://social.msdn.microsoft.com/Forums/en-US/759cbe5c-729d-477d-832e-c8ffb4098055/ef5-mapping-of-clr-type-to-edm-type-is-ambiguous-error?forum=adodotnetentityframework that the team was aware and looking into it for EF6.

I'm running EF 6.1 and still running into this issue. It has been reported on Sep 4, 2012 and still absolutely nothing to fix it, not even a temporary fix that does not involve horrible conventions for naming our tables.

This should really have a much higher priority than it has been getting... it's ridiculous...

Cupcake wrote Aug 9, 2015 at 12:48 PM

ooo this is soo bad! just can believe it. And no priority is seemed to be given to it. Wow just wow! Cupcake wrote Aug 9, 2015 at 12:51 PM

I need to maintain the table names and not change them. what then do I do?

clyjr wrote Aug 10, 2015 at 6:05 AM

I can't believe this bug has been unfixed for so long. I'm working on a conversion project where 6-10 databases being converted are going to have the same table names. I have been using database first without issues until I just now ran into the first database that has duplicate table names. This should really have a higher priority and get fixed, it's pretty sad that a bug of this magnitude can go unfixed for 4-5 years...

aL3891 wrote Aug 12, 2015 at 3:19 AM

Very sad to see this issue being ignored. between CF and EF7 not supporting generating stored procs and this issue you're really putting your users in a tough spot.

You recommend using EF 6 and claim that it will be supported even after EF7 but those words ring pretty hollow when seeing something like this.

mihaikanyaro wrote Aug 25, 2015 at 5:47 AM

I have a project with 3 modules, which share class names, mapped under different SQL schemas. All went fine and dandy (except the fact that you can enable migrations on a single context) with the Code First implementation, until I've hit the aforementioned problem. Thanks Microsoft, next time I'll think twice before choosing EF against NHibernate.

delmontyb wrote Jan 15, 2016 at 1:12 PM

Does anyone have a good idea for a work around? I'm trying to think about how I want to move forward, as I have two databases for this application. Hum...

Really hoping we'll see this resolved soon. Thanks

divega wrote Feb 4, 2016 at 1:41 PM

In case it helps, in one of the most recent minor releases of EF6.x we added annotations that can be put in entity types in the EDMX to identify the CLR type they will be mapped at runtime deterministically, which avoids scanning assemblies for all possible candidate CLR types and avoids the exception.

The EDMX needs to be edited manually to add the annotations since the tools won't add them. For a simple model with a Person entity, the ConceptualModels section of the EDMX would look like this:

<ConceptualModels>
    <Schema Namespace="ConsoleApplication33" 
        Alias="Self" 
        annotation:UseStrongSpatialTypes="false"
        xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" 
        xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" 
        xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
    <EntityType Name="Person" 
        customannotation:ClrType="MyApp.Person, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <Key>
        <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
        <Property Name="Name" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" />
    </EntityType>
    <EntityContainer Name="Town" customannotation:UseClrTypes="true">
        <EntitySet Name="People" EntityType="Self.Person" />
    </EntityContainer>
    </Schema>
</ConceptualModels>

Notice in particular the customannotation:ClrType on the Person entity type and the customannotation:UseClrTypes on the entity container.

saeb-panahifar commented 7 years ago

Thanks.

OskarKlintrot commented 6 years ago

It seems like I have to set customannotation on every single EntityType or else it wont work. Is there not way to tell customannotation:UseClrTypes to only use it on some or if available or something like that?

ajcvickers commented 6 years ago

@OskarKlintrot The annotation was created primarily for use by Code First where is is always set on every type. It was never implemented to only have it set in some cases. This is likely possible to implement and we would likely consider accepting a well written PR for this, but if I remember correctly it would involve merging too separate code paths into one and so may not be trivial.

OskarKlintrot commented 6 years ago

That makes sense, thanks @ajcvickers!

kabua commented 6 years ago

Can I get an example of how to use customannotation:UseClrTypes in a Code-First environment?

Thanks.

ajcvickers commented 6 years ago

@kabua Code First adds these annotations automatically--that's actually where they came from in the first place. So there is nothing special to do in Code First.

kabua commented 6 years ago

@ajcvickers thanks for the quick reply. But I'm having problems with the following very simple example:

    class Program
    {
        static void Main(string[] args)
        {
        }
    }

    public class MyContext : DbContext
    {
        public MyContext()
        {
        }

        public IDbSet<A.Person> APersons { get; set; }
        public IDbSet<B.Person> BPersons { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
    }

    namespace A
    {
        public class Person
        {
            public string Name { get; set; }
        }
    }

    namespace B
    {
        public class Person
        {
            public string Name { get; set; }
        }
    }

I get the following error:

The type 'EF_DuplicateSimpleTypeNames.B.Person' and the type
'EF_DuplicateSimpleTypeNames.A.Person' both have the same simple name of 'Person' and 
so cannot be used in the same model. All types in a given model must have unique simple names. 
Use 'NotMappedAttribute' or call Ignore in the Code First fluent API to explicitly exclude a 
property or type from the model.

Note: in the database we want two difference schema. I.e. table A.Person and table B.Person.

Any way to get this example to work? Thanks.

ajcvickers commented 6 years ago

@kabua EF6 cannot be used with two types in the same model that both have the same simple name. The changes made to Code First and the use of these attributes mean that if there is one mapped type with a given name and one unmapped type a given name, then EF will correctly use the mapped type instead of failing. I see that the comment above doesn't say that exactly, so I will go update it to be more clear.

kabua commented 6 years ago

We were afraid of that. :(

OskarKlintrot commented 6 years ago

@kabua Wouldn't be possible to use the TableAttribute?

[Table("APerson")]
public class Person
{ }

[Table("BPerson")]
public class Person
{ }
kabua commented 6 years ago

It is something we have looked at. I'm not sure which direction the team decided on. Use the table attribute or just prefix one of the Dto names. I was hoping for a more elegant and correct solution.

On Feb 22, 2018 8:15 AM, "Oskar Klintrot" notifications@github.com wrote:

@kabua https://github.com/kabua Wouldn't be possible to use the TableAttribute https://msdn.microsoft.com/en-us/library/jj591583%28v=vs.113%29.aspx?f=255&MSPPError=-2147217396#Table%20and%20Column ?

[Table("APerson")] public class Person { }

[Table("BPerson")] public class Person { }

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aspnet/EntityFramework6/issues/362#issuecomment-367693526, or mute the thread https://github.com/notifications/unsubscribe-auth/AH_RRmXVWadTztJtvqEB3TIM2JpleyDtks5tXXacgaJpZM4PauuQ .

ajcvickers commented 6 years ago

@OskarKlintrot @kabua Specifying different tables will not help. This is a problem with the way the EDM is defined and parsed by EF and is not easy to change. EF Core does not have this issue mainly because EF doesn't use EDM.

billbogaiv commented 6 years ago

Internally, does EF share model-mappings across multiple, distinct contexts in the same assembly? I have two independent contexts with two independent models, but still get the ...All types in a given model must have unique simple names... error.

namespace A
{
    public class Model
    {
    }

    public class FirstContext : DbContext
    {
        public IDbSet<Model> Models { get; set; }
    }
}

namespace B
{
    public class Model
    {
    }

    public class SecondContext : DbContext
    {
        public IDbSet<Model> Models { get; set; }
    }
}
patxiba commented 6 years ago

Hello, Is there a solution to this limitation of using in the same context two entities with the same name but in different namespace?

jsimmonstx commented 5 years ago

Allow me to add my voice to the din. FIX YOUR CRAP! Updating to EF7 is NOT possible for us! Using another ORM is NOT possible for us! Your apathetic approach to product maintenance is beyond insulting to your most important users (that would be developers, just in case you were wondering).

Vijay-Nirmal commented 5 years ago

Any Update?

patxiba commented 5 years ago

No, esto es una de las peores cosas que tiene EntityFramework 6

carloscatral commented 4 years ago

"Like" if you want an update for this question!!

CorsairRO commented 4 years ago

Hello, I am moving a big app >1000 tables from WinForms + EF5 ( ObjectContext ) to the new lightweight EF 6.4.0 DbContext.

However I find this as very frustrating that I cannot have the same class in 2 different namespaces.

I don't understand how this can be closed? You are developing an ORM for only apps with 3-4 tables in it? Preferably that have only 1 context for the whole app?

If the namespaces are ignored by EF, then why is it mandatory to type when you add a new ADO.NET EF Data Model there?

I really don't get it how it cannot be an issue since it has more than 8 years old and people are still complaining about it. How hard can it be to include a setting there in edmx for that? ANd in the typeresolver use NAMESPACES of the classes if the setting is there.

I don't want to have a project with 100+ assemblies, 1 for each of my domin namespaces. This approach however will work for smaller apps.

If this is too complicated, Is there any way for me to EXTEND from the classes that does the generation of edmx? I think I can fix this in 5 minutes if I can extend a class from somewhere and just override the resolve type.

Also a very very frustrating thing about edmx is that it has properties like customannotations that don't work in any automated way. THey are totally disconnected in CSDL from POCO Classes. Anyway, I tried to manually set in CSDL the solution recommended and it doesn't do anything.

Another BIG issue is that I have to go manually to ALL my table entities in edmx and set the ConcurrencyMode = Fixed for my RowVersion columns... Now, how hard can it be to be automatically done, or based on a setting of edmx.

Also, I am using Database First approach as you can imagine in my scenario with real apps I cannot use the strange codefirst / modelfirst approaches.

I thought I found a very nice solution to do that: Changing .t4 for my entities to include an attribute for [System.DataAnnotations.Timestamp] for my columns.

Surprise, it is getting ignored by ctx.SaveChanges();

I checked and setting it in edmx to Fixed just sets in in CSDL model. Again, a Major mismatch between CSDL and POCO Classes.

I am already thinking to go and buy some more professional ORM from the market as I cannot afford to wait another 8 years to solve an issue that takes 10 minutes.

Thank you for your understanding.

Please try to work for 10 minutes if you can with POCO classes like I have today:

INV_OR_PO_Order FIN_IN_Order SLS_IN_OR_PO_Order

Then you will probably agree with me

Seabizkit commented 3 years ago

still no solution to this issue, this is really annoying.. EF6 is amazing but not able to handle this really? Surely a fix can be done for this?