非必需对象字段上的实体框架验证错误

本文关键字:实体 框架 验证 错误 对象 字段 | 更新日期: 2023-09-27 18:06:12

我有一个ASP。. NET MVC网站,它将ViewModels传递给WebAPI服务,以便首先使用实体框架代码对数据库中的对象执行CRUD操作。

我的一个域实体对象是一个业务,它有业务信息、地址、主要联系人和次要联系人。问题是,二级联系人对象是不需要的,因为不是所有的公司都会有二级联系人。我已经将ID字段设置为可空,但是当我尝试将新的业务记录保存到没有辅助联系人对象的数据库中时,它会给我实体验证错误,认为需要辅助联系人记录字段。

有没有人知道如何停止这个错误,这样我就可以在没有二次联系人的情况下将业务实体保存在数据库中?

下面是相关代码。我使用automapper在我的视图模型和模型之间进行映射。

域业务对象

    public class Business
{
    public Guid PrimaryContactId { get; set; }
    [ForeignKey("PrimaryContactId")]
    [Required]
    public virtual Contact PrimaryContact { get; set; }
    public Guid? SecondaryContactId { get; set; }
    [ForeignKey("SecondaryContactId")]
    public virtual Contact SecondaryContact { get; set; }
    [Key]
    public Guid Id { get; set; }
    [Required]
    [MaxLength(100)]
    public string CompanyName { get; set; }
    [MaxLength(100)]
    public string CompanyWebsite { get; set; }
    [Required]
    [MaxLength(100)]
    public string Industry { get; set; }
    [Required]
    public NumberOfEmployees NumberOfEmployees { get; set; }
    [Required]
    public CommunicationPreference CommunicationPreference { get; set; }
    public Guid AddressId { get; set; }
    [ForeignKey("AddressId")]
    [Required]
    public virtual Address Address { get; set; }
}

业务视图模型

public class BusinessViewModel
{
    public Guid PrimaryContactId { get; set; }
    public PrimaryContactViewModel PrimaryContact { get; set; }
    public Guid? SecondaryContactId { get; set; }
    public SecondaryContactViewModel SecondaryContact { get; set; }
    public Guid Id { get; set; }
    [DisplayName("Company Name")]
    [Required]
    [MinLength(3, ErrorMessage = "Your {0} must be at least {1} characters long")]
    [MaxLength(100, ErrorMessage = "Your {0} must be no more than {1} characters")]
    public string CompanyName { get; set; }
    [DisplayName("Company Website")]
    [MinLength(3, ErrorMessage = "Your {0} must be at least {1} characters long")]
    [MaxLength(100, ErrorMessage = "Your {0} must be no more than {1} characters")]
    public string CompanyWebsite { get; set; }
    [DisplayName("Industry")]
    [Required]
    [MinLength(3, ErrorMessage = "Your {0} must be at least {1} characters long")]
    [MaxLength(100, ErrorMessage = "Your {0} must be no more than {1} characters")]
    public string Industry { get; set; }
    [DisplayName("Number of Employees")]
    [Required]
    public NumberOfEmployees NumberOfEmployees { get; set; }
    [DisplayName("Communication Preference")]
    [Required]
    public CommunicationPreference CommunicationPreference { get; set; }
    public Guid AddressId { get; set; }
    [Required]
    public AddressViewModel Address { get; set; }
}

域联系人对象

    public class Contact
{
    [Key]
    public Guid Id { get; set; }
    [Required]
    public Salutations? Prefix { get; set; }
    [Required]
    [MaxLength(100)]
    public string FirstName { get; set; }
    [Required]
    [MaxLength(100)]
    public string LastName { get; set; }
    [Required]
    [MaxLength(100)]
    public string JobTitle { get; set; }
    [Required]
    [DataType(DataType.EmailAddress)]
    [MaxLength(100)]
    public string Email { get; set; }
    [Required]
    [MaxLength(100)]
    public string Phone { get; set; }
    [MaxLength(100)]
    public string PhoneExtension { get; set; }
}

Base Contact View Model

    public class BaseContactViewModel
{
    public Guid Id { get; set; }
    [DisplayName("Primary Contact Prefix")]
    public virtual Salutations Prefix { get; set; }
    [DisplayName("Primary Contact First Name")]
    [MinLength(3, ErrorMessage = "Your {0} must be at least {1} characters long")]
    [MaxLength(100, ErrorMessage = "Your {0} must be no more than {1} characters")]
    public virtual string FirstName { get; set; }
    [DisplayName("Primary Contact Last Name")]
    [MinLength(3, ErrorMessage = "Your {0} must be at least {1} characters long")]
    [MaxLength(100, ErrorMessage = "Your {0} must be no more than {1} characters")]
    public virtual string LastName { get; set; }
    [DisplayName("Primary Contact Job Title")]
    [MinLength(3, ErrorMessage = "Your {0} must be at least {1} characters long")]
    [MaxLength(100, ErrorMessage = "Your {0} must be no more than {1} characters")]
    public virtual string JobTitle { get; set; }
    [DisplayName("Primary Contact Email Address")]
    [DataType(DataType.EmailAddress)]
    [MinLength(3, ErrorMessage = "Your {0} must be at least {1} characters long")]
    [MaxLength(100, ErrorMessage = "Your {0} must be no more than {1} characters")]
    public virtual string Email { get; set; }
    [DisplayName("Primary Contact Phone")]
    [DataType(DataType.PhoneNumber)]
    [MinLength(3, ErrorMessage = "Your {0} must be at least {1} characters long")]
    [MaxLength(100, ErrorMessage = "Your {0} must be no more than {1} characters")]
    public virtual string Phone { get; set; }
    [DisplayName("Primary Contact Extension")]
    [MinLength(3, ErrorMessage = "Your {0} must be at least {1} characters long")]
    [MaxLength(100, ErrorMessage = "Your {0} must be no more than {1} characters")]
    public virtual string PhoneExtension { get; set; }
}

辅助联系人视图模型

public class SecondaryContactViewModel : BaseContactViewModel
{
    [DisplayName("Secondary Contact Prefix")]
    public override Salutations Prefix { get; set; }
    [DisplayName("Secondary Contact First Name")]
    public override string FirstName { get; set; }
    [DisplayName("Secondary Contact Last Name")]
    public override string LastName { get; set; }
    [DisplayName("Secondary Contact Job Title")]
    public override string JobTitle { get; set; }
    [DisplayName("Secondary Contact Email Address")]
    public override string Email { get; set; }
    [DisplayName("Secondary Contact Phone")]
    public override string Phone { get; set; }
    [DisplayName("Secondary Contact Extension")]
    public override string PhoneExtension { get; set; }
}

保存EF的方法

public async Task<bool> CreateBusinessAsync(BusinessViewModel businessViewModel)
    {
        try
        {
            // TODO: Move mapping to some common place?
            Mapper.CreateMap<BusinessViewModel, Business>();
            Mapper.CreateMap<BaseContactViewModel, Contact>();
            Mapper.CreateMap<AddressViewModel, Address>();

            Business business = Mapper.Map<Business>(businessViewModel);
            //TODO: See why EntityFramework isn't automatically putting in GUIDs
            business.Id = Guid.NewGuid();
            business.Address.Id = Guid.NewGuid();
            business.PrimaryContact.Id = Guid.NewGuid();

            // Attach the objects so they aren't saved as new entries
            db.States.Attach(business.Address.State);
            db.Countries.Attach(business.Address.Country);
            //TODO: See why entity framework isn't automatically saving records
            var bus = db.Businesses.Add(business);
            var primary = db.Contacts.Add(business.PrimaryContact);
            if (!String.IsNullOrEmpty(business.SecondaryContact.FirstName))
            {
                business.SecondaryContact.Id = Guid.NewGuid();
                db.Contacts.Add(business.SecondaryContact);
            }
            else
            {
                business.SecondaryContact = null;
            }

            var address = db.Addresses.Add(business.Address);
            int rowsAffected = await db.SaveChangesAsync();

            if (bus != null && rowsAffected > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        catch (Exception e)
        {
            //TODO: Add exception logger
            string error = e.Message;
            return false;
        }
    }

请告诉我看其他课程是否有用。谢谢。

非必需对象字段上的实体框架验证错误

我以前有过类似的问题,我修复它的方法是将外键数据注释从属性中取出并使用fluent-api。使用fluent-api,我只是将关系的正确一侧标记为可选。

您可以根据文档将数据类型设置为可空

public class Foo {
// ...... Some property
[ForeignKey("tagId")]
public ICollection<SomeModel>? data {get; set;}
}

这将使属性不经过验证,并返回经过验证的结果。使用模型。IsValid