在TPT继承项目中具有valueinjector的视图模型中的自定义属性



我有一个视图模型,它使用valueinjector注入模型中的值(我还实现了TPT继承)。在这个过程中,由于我的一个自定义属性(不在模型源中的属性),我不断收到以下错误:

对象引用未设置为对象的实例。

我发现那个价值注入器时不时地会去那个地方。如下面的示例所示,自定义属性为"FullName"。

public class EmployeeVm
{
    public EmployeeVm(Employee employee)
    {
        this.InjectFrom<Employee>(employee);
    }
    public EmployeeVm(int id):this(new Context().Employees.Find(id))
    {
    }
    public EmployeeVm()
    {
    }
    public int EmployeeId { get; set; }
    [Display(Name = "First Name")]
    [Required(ErrorMessage = "Pleae enter First Name"), StringLength(50)]
    public string FirstName { get; set; }
    [Display(Name="Middle Name"), StringLength(50)]
    public string MiddleName { get; set; }
    [Display(Name="Last Name"), StringLength(50)]
    [Required(ErrorMessage = "Please enter Last Name")]
    public string LastName { get; set; }
    public string FullName {
        get
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("<b>");
            stringBuilder.Append(LastName.ToUpper());
            stringBuilder.Append("</b>");
            if (!string.IsNullOrEmpty(MiddleName))
            {
                stringBuilder.Append(", ");
                stringBuilder.Append(MiddleName);
            }
            stringBuilder.Append(", ");
            stringBuilder.Append(LastName);
            return stringBuilder.ToString();
        }
    }        
}

我想到的唯一解决方案是让valueinjector忽略该属性,这样它就不会在设置其他属性之前尝试获取该属性。为此,我尝试在员工模型中编写自定义注射器,如下所示:

[Table("Person")]
public abstract class Person:ConventionInjection
{
    public Person()
    {
        this.PersonAddresses = new List<PersonAddress>();
        this.PersonEmails = new List<PersonEmail>();
        this.PersonPhones = new List<PersonPhone>();
    }
    [Key]
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }

    //public virtual Employee Employee { get; set; }
    protected override bool Match(ConventionInfo c)
    {
      throw new NotImplementedException();
    }

    public List<PersonAddress> PersonAddresses { get; set; }
    public List<PersonEmail> PersonEmails { get; set; }
    public List<PersonPhone> PersonPhones { get; set; }
}
public class Employee:Person
{
    public Employee()
    {
        this.Identifications=new List<Identification>();
        this.BankAccounts=new List<BankAccount>();
    }
    public DateTime? DateOfBirth { get; set; }
    //Other properties are inherited from Person abstract class
    public virtual ICollection<Identification> Identifications { get; set; }
    public virtual ICollection<BankAccount> BankAccounts { get; set; }
    protected override bool Match(ConventionInfo c)
    {
        if (c.TargetProp.Name == "FullName")
        {
            return false;
        }

        var isMatch = (c.SourceProp.Name == "PersonId" && c.TargetProp.Name == "EmployeeId") ||
                      (c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Type == c.TargetProp.Type);
        return isMatch;
    }
}

尽管如此,我还是不断地犯上面提到的同样的错误。

我还找到了另一个解决方案,它说要覆盖LoopValueInjection的UseSourceProp方法。

http://valueinjecter.codeplex.com/discussions/234706

但是,在我的场景中这并不容易,因为我已经继承了基类和派生类中的一个类。实现自定义值注入器也是不可能的,因为您可以从EmployeeVm视图模型中看到它。

this.InjectFrom<Employee>(employee);

如果有人能帮助我实现这一点,或者有任何其他解决方案,我将不胜感激。

此外,还有观众的thanx。

试试这个:

在EmployeeVm:的构造函数中

public EmployeeVm(Employee employee)
{
    this.InjectFrom<Employee>(employee);
    stringBuilder = new StringBuilder();
    stringBuilder.Append("<b>");
    stringBuilder.Append(LastName.ToUpper());
     stringBuilder.Append("</b>");
     if (!string.IsNullOrEmpty(MiddleName))
     {
           stringBuilder.Append(", ");
           stringBuilder.Append(MiddleName);
     }
      stringBuilder.Append(", ");
     stringBuilder.Append(FirstName);
     this.FullName = stringBuilder.ToString();
}

将FullName属性转换为auto属性:

public string FullName { get; set; }

此外,将Employee中的覆盖方法更改为:

protected override bool Match(ConventionInfo c)
{
    var isMatch = (c.SourceProp.Name == "PersonId" && c.TargetProp.Name == "EmployeeId") ||(c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Type == c.TargetProp.Type);
      return isMatch;
}

您不需要重写LoopValueInjector的match属性或useSourceProp。匹配用于返回源和目标属性是否匹配,useSourceProp用于忽略SourceProperty,使其不映射到目标属性。

在您的场景中,源属性没有Full-Name属性,关于匹配,您不必像名称不匹配一样判断它不会映射属性。

错误是由于

LastName.ToUpper()

它试图在分配值之前将LastName属性转换为上限。因此,如果在valueinjector设置值之后在构造函数中设置值,那么问题就应该得到解决。

最新更新