mtanneryd / ef-bulk-operations

Bulk operations for Entity Framework 6

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Database generated Guid as Primary Keys

mihaivader opened this issue · comments

commented

Hello,

Thank you for the great work. These helpers that you put together are really helpful.
Any plans to support database generated Guid as Primary Keys?
Or any suggestions on how to do it?

Thank you :)

commented

Hello, again.
I've inserted a temporary IDENTITY Column on my tables which I drop after the query executes.
Works of Parent - Child relationship.
I'll try for more complex scenarios and I'll post here any updates.

Hi and thanks for your feedback.

At some point in time generated GUID primary keys actually did work. I might have lost that functionality recently for some reason. I'll have a look this week.

/Måns

commented

The Guid generated Ids work fine with the Temporary Identity column (I don't know if this is the best way to do it).

Also, I'm having some issues with another scenario:
I have a "Blog" which is one-to-many with "Post" which many-to-many to "Keywords", but for some reason, in the PostKeywords table it's trying to insert (PostId, KeyworkdId) - (Guid, Empty.Guid)

Any ideas?
Thanks

If you could post the code for those three classes I could run some tests. Also, when you say generated guid I assume that you mean that the guid ids are generated by the database and not by you?

commented

Yes, I'm talking about database generated Guid (newsequentialid())
As for the many to many relationship which isn't working for me,

[Table("Blog")]
public partial class Blog
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Blog()
    {
        Posts = new HashSet<Post>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    [StringLength(50)]
    public string Name { get; set; }

    [StringLength(500)]
    public string Description { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Post> Posts { get; set; }
}

[Table("Post")]
public partial class Post
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Post()
    {
        Keywords = new HashSet<Keyword>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public Guid BlogId { get; set; }

    [Required]
    [StringLength(50)]
    public string Title { get; set; }

    [StringLength(500)]
    public string Content { get; set; }

    public virtual Blog Blog { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Keyword> Keywords { get; set; }
}

public partial class Keyword
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Keyword()
    {
        Posts = new HashSet<Post>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    [StringLength(50)]
    public string Name { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Post> Posts { get; set; }
}

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .HasMany(e => e.Posts)
            .WithRequired(e => e.Blog)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Post>()
            .HasMany(e => e.Keywords)
            .WithMany(e => e.Posts)
            .Map(x =>
                {
                    x.ToTable("PostKeywords");
                    x.MapLeftKey("PostId");
                    x.MapRightKey("KeywordId");
                });
    }

I think I have a fix for your many-to-many issue. I tried it on a similar piece of code and could replicate and fix the issue. I haven't tried it on your specific code yet though.

commented

Nice :)

commented

Closed it accidentally.
I also made some changes around differences between property names and column names.
Also added support for SqlGeometry and SqlGeography types.
And support for Guid type for Id (database generated).

Are you interested in receiving these changes? :)

I would be happy to receive your changes. I'm not ready to add contributors to the project just yet but if you could email me the changes that would be great! You can reach me at mans@tanneryd.se.

commented

I'll email you tomorrow :)
If you could also update the code with the solution from Guid generated Ids, that would be great

commented

Hey.
Any updates on the Many to Many relationship?
Also have you considered supporting One to One relationships where the ID (database generated) from a table is also ID in another table? A PK , FK constraint.

Thanks

Hi!

The code currently in the repository works fine at least for the many-to-many relationships I have. It is a simple join table where identity primary keys from two tables form the primary key in the join table. The system I use this extension on also have several one-to-one relationships and they work just fine.

So, please try the latest version and let me know if it works or not. If not, please provide your failing example setup. I've had to deal with sick kids this week so I have been a bit pressed for time. As soon as possible I will create more test cases and verify that everything you have reported works as expected.

Again, thanks for your most welcome and very valuable feedback!

commented

Hello,

Sorry to hear about your children. Hope they're feeling better :)
I'll take the latest version of the code and have another go at it.
I'll keep you posted.
Thanks

commented

Hi :)

I've retried the many to many relation ship from scratch and it's working. I might have just screwed up the mappings in EF.
I've also got the One to One working with IDs that are both PK and FK and database generated. I had to make some minor tweaks.
I can resend you everything if you wish.

Cheers,
Mihai

The latest commit contains a fix for generated guid primary keys. It was a bit more complicated than I first expected but I think the current solution will work fine for all cases. Since the output parameter do not guarantee the returned guids to be in the same order as they were generated and since guids do not sort in a well behaved time fashion I needed to (ab)use the merge operation.

commented

Thanks for that :) I'll have a look

commented

I'll have a look now. i'll just have to merge your changes into mine, as I have some extra things added to my local version:

  • SQL Spatial types
  • Differences between C# property names and SQL column names
  • PK which are also FK

Both "Differences between C# property names and SQL column names" and "PK which are also FK" should work though. I have plenty of that in the software where I use this extension. If you have examples of that that does not work I would be happy to get some samples!

UPDATE: I remember now that you sent me some changes including property vs column names. I'll have a look at those and see if I can figure out why those were needed.

As far as I know and remember this has been fixed. If not, please reopen the issue.