在实体poco中使用自定义数据类型
本文关键字:定义数据类型 实体 poco | 更新日期: 2023-09-27 18:09:26
我有一个业务对象,比如User
。User
有一个PhoneNumber
字段,用字符串表示。出于最好留给我的原因,我创建了一个PhoneNumber
类,它具有隐式的to/from字符串操作符。我是否需要做任何特别的事情来获得PhoneNumber
作为字符串写入数据库?现在,实体已经决定把我的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; }
}
唯一的解决方法是:
// 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
列。
如果您的其余设计允许,您可以将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; }
}