开发者

Using custom datatypes in Entity POCOs?

开发者 https://www.devze.com 2023-04-08 12:25 出处:网络
I have a business object, say a User.A User has a PhoneNumber field, which is represented by a string.I, for reasons best left to me, have created a PhoneNumber class that has implicit to/from string

I have a business object, say a User. A User has a PhoneNumber field, which is represented by a string. I, for reasons best left to me, have created a PhoneNumber class that has implicit to/from string operators. Do I have to do anything special to get the PhoneNumber written as a string to the database? Right now, Entity has decided to break my PhoneNumber class up into its constituent parts (AreaCode, Prefix, etc) and save those to the database individually. PhoneNumber is stored in a separate assembly.

public class PhoneNumber : IEquatable<PhoneNumber>, IComparable<PhoneNumber>
{
    public static implicit operator string (PhoneNumber ph)
    {
        return ph.ToString ();
    }

    public static implicit operator PhoneNumber (string number)
    {
        return Parse(number);
    }

    public static PhoneNumber P开发者_运维百科arse(string number)
    {
       // ...
    }

    public override string ToString ()
    {
        // produce a Parse-compatible output
    }
}

public class User
{
    public virtual int Id { get; set; }
    public virtual string FirstName { get; set; }
    public virtual PhoneNumber Phone { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<User> Users { get; set; }
}


The only way is a workaround like this:

// You want to store in same table and not a navigation property, right?
// Then you need [ComplexType]
[ComplexType] 
public class PhoneNumber : IEquatable<PhoneNumber>, IComparable<PhoneNumber>
{
    // ...

    public string FullNumber
    {
        get
        {
            return Prefix + "-" + AreaCode + " " + Number; // or whatever
        }
        set
        {
            AreaCode = ParseToAreaCode(value); // or so...
            Prefix = ParseToPrefix(value);     // or so...
            Number = ParseToNumber(value);     // or so...
        }
    }

    [NotMapped]
    public string AreaCode { get; set; }
    [NotMapped]
    public string Prefix { get; set; }
    [NotMapped]
    public string Number { get; set; }
}

This way you would get only a FullNumber column in the database.


If the rest of your design allows it, you could leave the PhoneNumber class out of the mapping and let User handle a string representation of it, like:

public class User
{
  public virtual int Id { get; set; }
  public virtual string FirstName { get; set; }

  public virtual string PhoneNumber
  { 
      get { return this.PhoneNumber.ToString(); } // TODO: check for null
      set { this.PhoneNumber = PhoneNumber.Parse(value); }
  }

  [NotMapped]
  public virtual PhoneNumber Phone { get; set; }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消