How should I define a field that can take various

2019-07-18 16:27发布

问题:

My poco class is as follows;

public class FilterParameter
{
    public int Id { get; set; }

    [Required]
    public virtual UserFeatureSetting UserFeatureSetting { get; set; }

     [Required]
    [MaxLength(450)]
    public String ParameterName { get; set; }

    public object ParameterValue { get; set; }

}

but the generated migration code is not creating the ParameterValue field.

CreateTable("dbo.FilterParameters", c => new {
           Id = c.Int(nullable: false, identity: true),
           ParameterName = c.String(nullable: false, maxLength: 450),
           UserFeatureSetting_Id = c.Int(nullable: false),
   })
   .PrimaryKey(t => t.Id)
   .ForeignKey("dbo.UserFeatureSettings", t => t.UserFeatureSetting_Id, cascadeDelete: false)
   .Index(t => t.UserFeatureSetting_Id);

Is there an alternative type I should be using - or a work around?

回答1:

What's usually done is e.g.

// define your 'real field' as string, byte[] and/or define column type ntext, binary etc.
public string Value {get;set;}

// and make a wrapper property
[NotMapped]
public object ValueWrapper
{
    get { return YourParser.Deserialize(this.Value); }
    set { this.Value = value.Serialize(); }
}  

...and use some parser/formatter - serialization of some sort (depending on whether what you have is better represented by text, blob, xml etc.).

You should of course 'cache' the deserialized value if expensive etc.

Also, you may or may not need to store the ParameterType alongside - which depends on your object and serialization format basically.

e.g. EF/code-first uses binary to store the Edmx model into __MigrationHistory table - and they use the same approach (lower-level just).

If you only need to save/load different 'primitive types' each time (like once it's int, another time it's text etc.)

...then you may have some more options (inheritance maybe etc.) - but nothing I'd recommend much.
I prefer the first approach over any other as that kind of data is likely not usable in terms of relationships, so it doesn't matter how you store it most of the time.



回答2:

Entity Framework will map .Net types to SQL types. You shouldn't be using System.Object as EF doesn't know what SQL type to map it to. It's not ideal, but if you really need to have a column in the database with any object, use string ParameterValue and convert the value when you load it from the database. If required you could also add a new field string ParameterValueType where you would save the type of the value to help you converting it back.



回答3:

I think you can use a Dictionary<string, string> as the .NET data type to use in your domain model and de/serialize it on save/load time in json format which is clear text, and you can inspect the contents in Sql Server and even change it.

Glad to see you moving on :-)