简体   繁体   English

在实体POCO中使用自定义数据类型?

[英]Using custom datatypes in Entity POCOs?

I have a business object, say a User . 我说一个业务对象,一个User A User has a PhoneNumber field, which is represented by a string. User具有一个由字符串表示的PhoneNumber字段。 I, for reasons best left to me, have created a PhoneNumber class that has implicit to/from string operators. 出于最好的考虑,我创建了一个PhoneNumber类,该类隐含了字符串操作符。 Do I have to do anything special to get the PhoneNumber written as a string to the database? 我是否需要做一些特殊的事情才能将PhoneNumber作为字符串写入数据库? 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. 现在,Entity已经决定将我的PhoneNumber类分解为它的组成部分( AreaCodePrefix等),并将它们分别保存到数据库中。 PhoneNumber is stored in a separate assembly. 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; }
}

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. 这样,您将在数据库中仅获得FullNumber列。

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: 如果设计的其余部分允许,则可以将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; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM