0

I am trying to setup a product key system in my application, but I want to ensure the attribute has the right size (16 characters).

I tried the following

public class ProductKey
{
    public const int ProductKeyLength = 16;

    [StringLength(ProductKeyLength, MinimumLength = ProductKeyLength)]
    private string _value;

    [Required]
    [Index(IsUnique = true)]
    public string Value {
        get
        {
           var temp = Regex.Replace(this._value, ".{4}", "$0-");
            return temp.Trim('-');
        }
        set { this._value = value.Replace("-", "");}
    }


}

I want to enable the user to insert the key with our without hyphen. I get the following error with above code:

Column 'Value' in table 'dbo.ProductKeys' is of a type that is invalid for use as a key column in an index.

As I understood, I need to set a limit to Value so it can be used as a unique key. But, _value has a limit and _value is the actual representation of Value in the database.

Is there a way to set the limit correctly in this case?

Thanks in advance.

Richard
  • 29,854
  • 11
  • 77
  • 120
Vitor Durante
  • 950
  • 8
  • 25

1 Answers1

0

You are getting the error because without a StringLength attribute on the Value field, the database column gets created as VARCHAR(MAX) which cannot be used as a key. You need a [StringLength] on the field being used as a key. However, as your getter is returning the key formatted with dashes, you need the key length to be 19:

public class ProductKey
{
    public const int ProductKeyLength = 19;

    private string _value { get; set; }

    [Key]
    [Required]
    [StringLength(ProductKeyLength, MinimumLength = ProductKeyLength)]
    [Index(IsUnique = true)]
    public string Value
    {
        get
        {
            var temp = Regex.Replace(this._value, ".{4}", "$0-");
            return temp.Trim('-');
        }
        set { this._value = value.Replace("-", ""); }
    }
}

You might be better off doing your format conversion in ViewModels and client-side code, as one problem you'll have here is searching - for example...

db.Keys.Add(new ProductKey { Value = "1234-5678-9012-3456" });
db.Keys.Add(new ProductKey { Value = "1234567890123455" });
db.SaveChanges();

Console.WriteLine(db.Keys.Count(k => k.Value.Contains("89")));  // 0
Console.WriteLine(db.Keys.Count(k => k.Value.Contains("8-9"))); // 2
Richard
  • 29,854
  • 11
  • 77
  • 120
  • Okay, the automatic migration is not setting up the stringlength automatically. I will do it manually then – Vitor Durante Jun 06 '16 at 21:13
  • Don't do it manually, that means your model will be out of sync with the database. Fix the model so that the migrations work, not the other way round. – Richard Jun 06 '16 at 21:18