Использование пользовательских типов данных в объектах POCO? - PullRequest
0 голосов
/ 23 сентября 2011

У меня есть бизнес-объект, скажем User.User имеет поле PhoneNumber, которое представлено строкой.По причинам, которые мне лучше всего оставлены, я создал класс PhoneNumber, который имеет неявные операторы строки / из строки.Нужно ли делать что-то особенное, чтобы записать PhoneNumber в виде строки в базу данных?Прямо сейчас Entity решила разбить мой класс PhoneNumber на составные части (AreaCode, Prefix и т. Д.) И сохранить их в базе данных индивидуально.PhoneNumber хранится в отдельной сборке.

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 Parse(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; }
}

Ответы [ 2 ]

3 голосов
/ 23 сентября 2011

Если остальная часть вашего проекта это позволяет, вы можете исключить класс PhoneNumber из сопоставления и позволить User обработать его строковое представление, например:

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; }
}
3 голосов
/ 23 сентября 2011

Единственный способ - это обходной путь, подобный следующему:

// 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; }
}

Таким образом вы получите только столбец FullNumber в базе данных.

...