C# 在实体POCO中使用自定义数据类型?
我有一个业务对象,比如C# 在实体POCO中使用自定义数据类型?,c#,entity-framework-4.1,poco,C#,Entity Framework 4.1,Poco,我有一个业务对象,比如用户。用户有一个电话号码字段,由字符串表示。一、 出于最好留给我的原因,我创建了一个PhoneNumber类,该类具有隐式的to/from字符串运算符。要将PhoneNumber作为字符串写入数据库,我需要做什么特殊的事情吗?现在,实体已经决定将我的PhoneNumber类分解为它的组成部分(AreaCode,前缀,等等),并将它们分别保存到数据库中电话号码存储在单独的程序集中 public class PhoneNumber : IEquatable<PhoneNu
用户
。用户
有一个电话号码
字段,由字符串表示。一、 出于最好留给我的原因,我创建了一个PhoneNumber
类,该类具有隐式的to/from字符串运算符。要将PhoneNumber
作为字符串写入数据库,我需要做什么特殊的事情吗?现在,实体已经决定将我的PhoneNumber
类分解为它的组成部分(AreaCode
,前缀
,等等),并将它们分别保存到数据库中<代码>电话号码存储在单独的程序集中
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; }
}
公共类电话号码:IEquatable,IComparable
{
公共静态隐式运算符字符串(PhoneNumber ph)
{
返回ph.ToString();
}
公共静态隐式运算符PhoneNumber(字符串编号)
{
返回解析(数字);
}
公共静态电话号码解析(字符串号码)
{
// ...
}
公共重写字符串ToString()
{
//生成与解析兼容的输出
}
}
公共类用户
{
公共虚拟整数Id{get;set;}
公共虚拟字符串FirstName{get;set;}
公共虚拟电话号码电话{get;set;}
}
公共类MyContext:DbContext
{
公共数据库集用户{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; }
}
//您希望存储在同一个表中,而不是导航属性,对吗?
//然后您需要[ComplexType]
[复合类型]
公共类电话号码:IEquatable、IComparable
{
// ...
公共字符串完整编号
{
得到
{
返回前缀+“-”+区号+“”+数字;//或其他
}
设置
{
AreaCode=ParseToAreaCode(值);//大约。。。
Prefix=ParseToPrefix(值);//大约。。。
Number=parsetNumber(值);//大约。。。
}
}
[未映射]
公共字符串区域代码{get;set;}
[未映射]
公共字符串前缀{get;set;}
[未映射]
公共字符串编号{get;set;}
}
这样,您将在数据库中只获得一个
FullNumber
列。唯一的方法是这样的解决方法:
// 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; }
}
//您希望存储在同一个表中,而不是导航属性,对吗?
//然后您需要[ComplexType]
[复合类型]
公共类电话号码:IEquatable、IComparable
{
// ...
公共字符串完整编号
{
得到
{
返回前缀+“-”+区号+“”+数字;//或其他
}
设置
{
AreaCode=ParseToAreaCode(值);//大约。。。
Prefix=ParseToPrefix(值);//大约。。。
Number=parsetNumber(值);//大约。。。
}
}
[未映射]
公共字符串区域代码{get;set;}
[未映射]
公共字符串前缀{get;set;}
[未映射]
公共字符串编号{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; }
}
如果设计的其余部分允许,您可以将
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; }
}
Entityframework使用实体类并将每个属性表示为列,工作正常。您的PhoneNumber类是部分的吗?如果是,您可以在PhoneNumber类的none-generated部分中重写ToString()。这样一来,无论它如何存储在数据库中,对象都可以为您提供这些信息。它不是一个分部类,但对象确实重写了ToString(),并产生了我所期望的结果。我将更新一些示例代码。好吧,我想问题是,为什么要将电话号码存储为字符串而不是实体表示形式。EF总是将属性转换为列或列转换为属性,这取决于您是否先编写代码。在数据库中,有5列专门用于存储电话号码的数据块,而不是规范的“(101)555-1234”表示形式,这很尴尬。也许没什么大不了的?有什么尴尬的?拥有3个单独的字段将强制执行该格式,并允许每个应用程序以其想要的任何格式在内部显示字段。否则,您将需要担心101.555.1234对101-555-1234对(101)555-1234对1015551234。使用一个列,您将如何查询给定区号、exchange、国家/地区代码等的所有记录。如果将这些查询存储在部分中,则所有这些查询都更易于编写。Entityframework使用实体类并将每个属性表示为列,工作正常。您的PhoneNumber类是部分的吗?如果是,您可以在PhoneNumber类的none-generated部分中重写ToString()。这样一来,无论它如何存储在数据库中,对象都可以为您提供这些信息。它不是一个分部类,但对象确实重写了ToString(),并产生了我所期望的结果。我将更新一些示例代码。好吧,我想问题是,为什么要将电话号码存储为字符串而不是实体表示形式。EF总是将属性转换为列或列转换为属性,这取决于您是否先编写代码。在数据库中,有5列专门用于存储电话号码的数据块,而不是规范的“(101)555-1234”表示形式,这很尴尬。也许没什么大不了的?有什么尴尬的?拥有3个单独的字段将强制执行该格式,并允许每个应用程序以其想要的任何格式在内部显示字段。否则,您将需要担心101.555.1234对101-555-1234对(101)555-1234对1015551234。使用一列,您将如何查询