C# 将属性设置为另一个属性';s值
我对这一点很陌生,我的问题非常特殊。我在谷歌上搜索了很多,但都没有找到这方面的任何信息。我在数据库中有两个属性,StartDate和StartMonth。StartDate类型为DateTime,StartMonth类型为string。(我知道将这两个都保存到数据库中是愚蠢的,但这不是我可以更改的,因为我没有这样做的权限。)我的问题是,在DB模型中,如何将StartMonth设置为等于StartDate中的月份(因为它是相同的)?相反,正确的方法是什么?非常感谢您的帮助 明确地说,我目前有:C# 将属性设置为另一个属性';s值,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我对这一点很陌生,我的问题非常特殊。我在谷歌上搜索了很多,但都没有找到这方面的任何信息。我在数据库中有两个属性,StartDate和StartMonth。StartDate类型为DateTime,StartMonth类型为string。(我知道将这两个都保存到数据库中是愚蠢的,但这不是我可以更改的,因为我没有这样做的权限。)我的问题是,在DB模型中,如何将StartMonth设置为等于StartDate中的月份(因为它是相同的)?相反,正确的方法是什么?非常感谢您的帮助 明确地说,我目前有: [
[Table("EMPLOYMENT")]
public class Employment : EntityBase
{
[Column("STARTDATE")]
public DateTime? StartDate { get; set; }
[Column("STARTMONTH")]
public string StartMonth { get; set; }
}
编辑:
我尝试了以下方法(我意识到这不是任何建议,但是一位同事建议的):
具体地说,StartMonth现在是私有的,StartDate现在是一个NotMapped属性,它设置StartDateInternal和StartMonth并返回StartDateInternal值,前面代码中的原始StartDate现在命名为StartDateInternal。虽然我可以看到值一直正确地传递给模型,但它不会设置值。在数据库中,它总是将其设置为NULL。我不知道为什么,我想知道是否有人知道为什么。将您的setter标记为
private
,然后创建一个SetStartDate
方法来设置这两个属性
[Table("EMPLOYMENT")]
public class Employment : EntityBase
{
[Column("STARTDATE")]
public DateTime? StartDate { get; private set; }
[Column("STARTMONTH")]
public string StartMonth { get; private set; }
public string SetStartDate(DateTime? startDate)
{
this.StartDate = startDate;
this.StartMonth = startDate.HasValue ? startDate.Value.ToString("MMMM") : null;
}
}
另一种建模方法是将StartMonth
的setter标记为private
,并让StartDate的setter设置两个属性:
[Table("EMPLOYMENT")]
public class Employment : EntityBase
{
DateTime? startDate;
[Column("STARTDATE")]
public DateTime? StartDate
{
get { return this.startDate; }
set
{
this.startDate = value;
this.StartMonth = value.HasValue ? value.Value.ToString("MMMM") : null;
}
}
[Column("STARTMONTH")]
public string StartMonth { get; private set; }
}
只有在未设置StartMonth值的情况下,才可以使用支持字段,并从StartDate获取月份
private string _startMonth;
[Column("STARTMONTH")]
public string StartMonth
{
get
{
if (string.IsNullOrWhiteSpace(_startMonth) && StartDate.HasValue)
return StartDate.Value.ToString("MMMM");
return _startMonth;
}
set { _startMonth = value; }
}
您不应该映射StartMonth属性,因此它不会保存在数据库中,但模型仍将具有该属性。您可以执行以下操作:
[NotMapped]
public string StartMonth
{
get
{
return StartDate?.Month.ToString();
}
}
其中NotMapped属性告诉EF不要映射此属性,但您可以在代码中使用此属性。另外,您不需要set属性,因为StartMonth只返回StartDate month。这样可以确保StartMonth和StartDate.Month没有不同的值。可以更改数据库设计吗
如果是这样,请在数据库中使用触发器或其他工具将STARMONTH列呈现为伪列,返回STARTDATE列的“month”值
如果没有,则可以在处理新的开始日期时设置开始月份:
[Table("EMPLOYMENT")]
public class Employment
{
private DateTime _StartDate;
[Column("STARTDATE")]
public DateTime StartDate
{
get
{
return _StartDate;
}
set
{
_StartDate = value;
StartMonth = value.ToString("MMMM") ?? null;
}
}
[Column("STARTMONTH")]
public string StartMonth { get; set; }
}
数据库伪列将保证所有DB客户端的结果一致。上述代码适用于任何使用此代码的情况 您可以直接从表中更改表架构,如果可以的话,可以设置STARTMONTH=Datepart(mm,STARTDATE),但我没有权限修改表架构,我们的表是从Oracle数据库(Oracle到SQL)中提取的因此,弄乱模式也可能会打乱这一过程。有人可能在这里向自己的脚开枪。new Employment(){StartDate=new DateTime(12,1,1),startmonh=“一月”}
是的,这是可能发生的。问题是,如果StartMonth没有setter,实体框架将抛出异常。如果您根本不信任设置值,那么只需删除string.IsNullOrWhiteSpace(_startMonth)
。看起来StartMonth来自数据库,因此需要一个setter。如果在整个代码中使用setter,这会破坏所有内容,并且您100%确定StartMonth和StartDate始终设置在一起并且正确。。。将该属性标记为,它将告诉其他开发人员以后不要使用它,并添加一个setter,该setter记录警告,但不执行其他操作。。。即使您确定,也可以运行完整的测试套件并检查您收到的所有警告。Erik表示,他不能干扰数据库设计,这使我相信该数据库很可能按照旧的大型机设计(如VSAM、DL/1或IDMS)进行建模。当与具有旧根的图案一起储存时,经常会看到日期被分割成不同的部分。无论哪种方式,如果他的应用程序要更新此数据库,他必须选择一种其他使用该数据库的应用程序可以接受的技术。谁是Erik?无论哪种方式,它都不能被更改。将集合设置为私有是做什么的?或者,更确切地说,为什么要这样做?主要原因是防止用户射中自己的脚。他们可以指定一个StartDate
,该日期将自动计算StartMonth
。他们没有办法为这些字段指定冲突的值。。。如果不跳转,他们(甚至你)就没有办法搞乱这些价值观。这两列都将通过为StartDate
指定一个值自动设置。很遗憾,我无法更改数据库设计。不过,我确实尝试过类似于你建议的东西。我编辑了我的问题以反映它。
[Table("EMPLOYMENT")]
public class Employment
{
private DateTime _StartDate;
[Column("STARTDATE")]
public DateTime StartDate
{
get
{
return _StartDate;
}
set
{
_StartDate = value;
StartMonth = value.ToString("MMMM") ?? null;
}
}
[Column("STARTMONTH")]
public string StartMonth { get; set; }
}