Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HierarchyId support #30

Closed
rmaenk opened this issue Mar 13, 2019 · 16 comments
Closed

HierarchyId support #30

rmaenk opened this issue Mar 13, 2019 · 16 comments
Assignees

Comments

@rmaenk
Copy link

rmaenk commented Mar 13, 2019

Hello,
We have a license for EF Classic, but cannot migrate our code to it because of absent HierarchyId support.
It would be very helpful if HierachyId will be introduced. We used EF beta nightly build and everything is OK. More details here: dotnet/ef6@f905073.
Thanks, Roman

@JonathanMagnan
Copy link
Member

Hello @roamel ,

Thank you for reporting.

We will look at it and merge this pull as well.

I believe it should be available for next Monday.

Best Regards,

Jonathan

@JonathanMagnan JonathanMagnan self-assigned this Mar 13, 2019
@JonathanMagnan
Copy link
Member

Hello @roamel ,

The v7.0.39 has been released.

Could you try it and let us know if everything is working for HierarchyId?

@rmaenk
Copy link
Author

rmaenk commented Mar 17, 2019

Hello @JonathanMagnan,

I will look into this in few days

Regards,
Roman

@rmaenk
Copy link
Author

rmaenk commented Mar 31, 2019

Hello @JonathanMagnan

I have tested the next versions: 7.0.39, 7.0.40 and 7.1.1
For all these versions basic functionality of HierarchyID is working well, like in EF beta version we use.

However, there is an issue with Bulk operations:

Server Error in '/' Application.

Type not supported yet (LazyType): hierarchyid 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Exception: Type not supported yet (LazyType): hierarchyid

Source Error: 



Line 169: }
Line 170: if (addEntities.Any()) {
Line 171: _cntx.BulkInsert(addEntities);
Line 172: //using (var bulk = new Z.BulkOperations.BulkOperation<UserDiscipline>(_cntx.Database.Connection)) {
Line 173: // bulk.Connection.Open();

Stack Trace:

[Exception: Type not supported yet (LazyType): hierarchyid]
.(String , PrimitiveType ) +433
<>c.(Property ) +13
System.Collections.Generic.List`1.ForEach(Action`1 action) +85
.(SchemaEntityType ) +680
System.Collections.Generic.List`1.ForEach(Action`1 action) +85
.(Schema , Boolean ) +70
.(Schema , Boolean ) +42
.(XDocument ) +591
.(DbContext ) +151
.(DbContext ) +135
.(DbContext this) +123
.(DbContext this, String ) +36
.(DbContext this, BulkOperation`1 , IEnumerable`1 , List`1 ) +224
.(BulkOperation`1 this, DbContext , IEnumerable`1 , List`1 ) +59
DbContextExtensions.BulkInsert(DbContext this, IEnumerable`1 entities, Action`1 bulkOperationFactory) +889
DbContextExtensions.BulkInsert(DbContext this, IEnumerable`1 entities) +55

If we use Z.BulkOperations.BulkOperation directly - bulk insert works without errors. Like this:

                //_cntx.BulkInsert(addEntities);
                using (var bulk = new Z.BulkOperations.BulkOperation<UserDiscipline>(_cntx.Database.Connection)) {
                    bulk.Connection.Open();
                    bulk.BulkInsert(addEntities);
                    bulk.Connection.Close();
                }

Model is the next (simplified):

    public partial class UserDiscipline {
        public int Id { get; set; }
        public int UserId { get; set; }
        public int DisciplineId { get; set; }
        public virtual Discipline Discipline { get; set; }
        public virtual User User { get; set; }
    }
    [Serializable]
    public partial class Discipline {
        public Discipline() {
            this.Folders = new List<Folder>();
            this.UserDisciplines = new ObservableCollection<UserDiscipline>();
        }

        public int Id { get; set; }
        public virtual ICollection<Folder> Folders { get; set; }
        public virtual ObservableCollection<UserDiscipline> UserDisciplines { get; set; }
    }

    [Serializable]
    public partial class Folder  {
        public Folder() {
            this.Children = new List<Folder>();
        }

        public int Id { get; set; }
        public Nullable<int> ParentFolderId { get; set; }
        public HierarchyId Hid { get; set; }
        public Nullable<int> DisciplineId { get; set; }
        public virtual Discipline Discipline { get; set; }
        public virtual ICollection<Folder> Children { get; set; }
        public virtual Folder Parent { get; set; }
    }

Additionally, not sure is it related to the issue or not, we still use standard EF in parallel, because of Microsoft.AspNet.Identity.EntityFramework package.

Standard EF and Z.Classic both uses the same assembly with models and each load dynamically created assembly with the same full qualified name: EntityFrameworkDynamicProxies-{assembly name here},1.0.0.0.

This may be a cause of the issue, may be not, but 2 assemblies, with the same name, conflict each other during deserialization of proxies. I may suggest to use different assembly name for EntityFrameworkDynamicProxies in Z.Classic, like this:
ZEntityFrameworkClassicDynamicProxies-{assembly name here}.(you can look at the code here \src\Shared\EntityFramework\Core\Objects\Internal\EntityProxyFactory.cs)

So, we have some progress with migarting to the library, but it still has some issue that would be good to resolve.

Regards,
Roman

@JonathanMagnan
Copy link
Member

Hello @roamel ,

You are right, we forget to add it in our EF Extensions library. I believe this request will be very easy (probably very similar to how we did it with SqlGeometry and SqlGeography).

We also added a task with your suggestion for Dynamic Proxy. We will look at it and should be released this week as well if that's simple to implement.

Best Regards,

Jonathan

@JonathanMagnan
Copy link
Member

Hello @roamel ,

The v7.1.2 has been released.

HierarchyId should now work correctly with Bulk Operations as well.

We will start to check about Dynamic Proxy very soon.

@rmaenk
Copy link
Author

rmaenk commented Apr 2, 2019

Hello @JonathanMagnan
Thanks for informing about this.
FYI: About Dynamic Proxies: To have both EF and Z.Classic in the same code we use extern aliases:
for referencing standard EF: alias in reference props has "EF6" value ("global" is removed)
for referencing Z.Classic: alias in reference props has "global" value
And in code before usings:
extern alias EF6;

static UsersContext() {
            EF6.System.Data.Entity.Database.SetInitializer<UsersContext>(null);
}

Regards,
Roman

@rmaenk
Copy link
Author

rmaenk commented Apr 3, 2019

Hello @JonathanMagnan
I have tested version 7.1.2 and can confirm that it works with Bulk Operations and HierarchyID without errors with our model.
Good work!

FYI: I have found that Update-Database powershel cmdlet does not work if EF context is based on Z.EntityFramework.Classic DBContext and config section name is not default (for instance entityFrameworkClassic instead of entityFramework):

    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <section name="entityFrameworkClassic" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, Z.EntityFramework.Classic, Version=7.0.0.0, Culture=neutral, PublicKeyToken=afc61983f100d280" requirePermission="false" />

To fix this static constructor of migration Configuration class can be used :

        static Configuration() {
            Z.EntityFramework.Classic.EntityFrameworkManager.ConfigSectionName = "entityFrameworkClassic";
        }

I know, that initially, Z.EntityFramework.Classic was positioned as replacement for standard EF6 and parallel usage of both libraries was not supported. But now, it looks possible and may help developers to use benefits of this approach. For instance, with packages that cannot be recompiled with Z.EntityFramework.Classic, like Microsoft.AspNet.Identity.EntityFramework.
What do you think about adding this to documentation?

Best Regards,
Roman

@JonathanMagnan
Copy link
Member

Yup it will for sure eventually be added in the doc, thank for sharing ;)

@rmaenk
Copy link
Author

rmaenk commented Apr 12, 2019

Hi @JonathanMagnan

Any news about Dynamic Proxy assembly name change?

Regards,
Roman

@JonathanMagnan
Copy link
Member

Hello @roamel ,

I modified the priority on this request.

It seems the priority was very low so was keeping being delayed by other requests.

I will contact you next Monday to give you an update about it. This request should be checked during the weekend and completed if possible.

Best Regards,

Jonathan

@JonathanMagnan
Copy link
Member

Hello @roamel ,

The v7.1.3 has been released.

We renamed the proxy class as you proposed.

Let me know if some request is still remaining or we can close this issue.

Best Regards,

Jonathan

@JonathanMagnan
Copy link
Member

Hello @roamel ,

We will close this issue,

If there is anything else, feel free to comment it here or open a new issue.

Best Regards,

Jonathan

@rmaenk
Copy link
Author

rmaenk commented May 7, 2019

Hello @JonathanMagnan
Sorry for delay.
Everything is working good.
Thanks a lot,
Roman

@mshojaei
Copy link

mshojaei commented Feb 3, 2020

Hello @JonathanMagnan
Sorry
I have a provlem when I want to use z.EntityFramework.Classic with Microsoft.AspNet.Identity.EntityFramework

the problem is that both of them used EF, and I cant use DbContext of Microsoft.AspNet.Identity.EntityFramework
can you guide me?
image

@JonathanMagnan
Copy link
Member

Hello @mshojaei ,

Please read the following page, it should help you: https://entityframework-classic.net/using-ef-classic-with-ef-6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants