Entity Framework: how to set the type of a column as uniqueidentifier with Fluent API

azure-mobile-services ef-code-first-mapping ef-fluent-api entity-framework-6 uniqueidentifier

Question

I use Entity Framework 6, code-first.

I have a column <string> Id that is created by a framework (Azure Mobile Server SDK), which I don't have access to.

public abstract class EntityData
{
    [Key]
    [TableColumn(TableColumnType.Id)]
    public string Id { get; set; }

    ...
}

If I don't perform any action, such column is mapped as a nvarchar(MAX) in SQL Server.

I have been able to turn it into a char(36) with this snippet in Fluent API:

PropertyConventionConfiguration pkConf = modelBuilder.Properties<string>().Where(p => p.Name == "Id");
pkConf.Configure(p => p.IsUnicode(false));
pkConf.Configure(p => p.HasMaxLength(36));
pkConf.Configure(p => p.IsFixedLength());

I want to set it as uniqueidentifier.

How can I do that with a similar Fluent API code snippet?

Thank you very much!

1
0
8/25/2018 6:43:45 AM

Accepted Answer

You can use a custom value converter or leverage the built in GuidToStringConverter : docs.microsoft.com/en-us/ef/core/modeling/value-conversions . A few side notes - you should create a class that inherits from this abstract class. This not only offers a layer of abstraction, it will also allow you to control more precisely how you store and access your data. Also, as you're probably aware, GUIDs make horrible PKs!

EDIT:

If you're using EF 6, this feature won't be available. You will therefore, need to create a wrapper property or use a stored procedure. Here's an example, sample code can be found here: https://github.com/ibrahm2/entityframework6-map-string-to-guid

Method 1: Wrapper Property

  1. Create a class that inherits from EntityData. For this example, let's call it WrapperTable e.g.
  2. Add a property called Id with type Guid and mask the base Id property by using the new modifier. Have it return a cast version of Id from the base class as Guid. This will mask the base property. It isn't best practice so if you're uncomfortable with this, the alternative would be to create a new property e.g. called Key that wraps around Id.
  3. If your configuration, map the inherited class to the EntityDate table.

    modelBuilder.Entity().ToTable("EntityData");

Method 2: Stored Procedure

  1. Create a stored procedure that takes in a varchar as a parameter for the Id field
  2. Map the stored procedure to the Insert function of the Entity e.g.:

    modelBuilder.Entity().MapToStoredProcedures(prop=>prop.Insert(sp=>sp.HasName("sp_InsertTable").Parameter(pm => pm.Id, "@id")));

  3. Have the stored procedure insert the varchar into your uniqueidentifier field.

1
8/30/2018 3:18:51 AM

Popular Answer

Here you go:

 modelBuilder.Entity<TodoItem>().Property(t => t.Id).HasColumnType("UniqueIdentifier");

More information for your reference:

Configuring the Data Type of a Database Column



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow