关于c#:将属性设置为另一个属性的值

Set property to another property's value

我对这个很陌生,我的问题很特别。我在网上搜了很多东西,都找不到。我在数据库中有两个属性,startdate和startmonth。startdate的类型为datetime,startmonth的类型为string。(我知道把这两个都保存到数据库中是愚蠢的,但这不是我可以更改的,因为我没有权限这样做。)我的问题是,在DB模型中,如何将startmonth设置为startdate中的月份(因为它是相同的)?相反,正确的方法是什么?任何帮助都非常感谢!

明确地说,我目前有:

1
2
3
4
5
6
7
8
9
[Table("EMPLOYMENT")]
public class Employment : EntityBase
{  
    [Column("STARTDATE")]
    public DateTime? StartDate { get; set; }

    [Column("STARTMONTH")]
    public string StartMonth { get; set; }
}

编辑:我尝试了以下方法(我意识到这不是建议中的任何一种,但它是由同事建议的):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[Table("EMPLOYMENT")]
public class Employment : EntityBase
{  
    [Column("STARTDATE")]
    internal DateTime? StartDateInternal { get; set; }

    [Column("STARTMONTH")]
    private string StartMonth { get; set; }

    [NotMapped]
    public DateTime? StartDate
    {
        get
        {
            return StartDateInternal;
        }
        set
        {
            StartDateInternal = value;
            StartMonth = value?.ToString("MMMM");
        }
}

具体地说,startmonth现在是私有的,startdate现在是一个notmapped属性,它设置startdateinternal和startmonth并返回startdateinternal值,并且以前代码中的原始startdate现在命名为startdateinternal。虽然我可以看到这个值被正确地传递到模型中,但它不会设置这个值。它总是在数据库中将其设置为空。我不知道为什么,想知道是否有人知道为什么。


您可以使用支持字段,并且只有在未设置StartMonth值的情况下才能从StartDate获取月份。

1
2
3
4
5
6
7
8
9
10
11
12
13
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; }
}


你能改变数据库的设计吗?

如果是这样,请使用触发器或数据库中的其他工具将StarMonth列呈现为返回StartDate列的"Month"值的伪列。

如果没有,则可以在处理新的开始日期时设置开始月份:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    [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属性,因此它不会保存在数据库中,但模型仍然具有该属性。你可以这样做:

1
2
3
4
5
6
7
8
    [NotMapped]
    public string StartMonth
    {
        get
        {
            return StartDate?.Month.ToString();
        }
    }

其中notmapped属性告诉ef不要映射此属性,但您可以在代码中使用此属性。另外,您不需要set属性,因为startmonth只返回startdate month。这样可以确保startmonth和startdate.month没有不同的值。


将您的setter标记为private,然后创建一个SetStartDate方法来设置这两个属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[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设置这两个属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[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; }
}