在多对多关系中插入失败

时间:2017-03-27 21:47:00

标签: c# asp.net-mvc entity-framework ef-code-first many-to-many

我正在开发一个实体框架代码优先项目,我有多对多的关系:ServiceProvider和ServiceType

将新的ServiceProvider添加到存储库时,我收到以下错误:无法将值NULL插入列'ID',表'ABCDE.dbo.ServiceTypes';列不允许空值。 INSERT失败。

实体和控制器类如下:

ServiceProvider.cs:

public partial class ServiceProvider
{
    public ServiceProvider()
    {
        ServiceTypes = new HashSet<ServiceType>();
    }

    [Key]
    public int ServiceProviderID { get; set; }

    [Required]
    [StringLength(100)]
    public string Title { get; set; }

    public virtual ICollection<ServiceType> ServiceTypes { get; set; }

    public virtual IEnumerable<Service> Services { get; set; }

}

ServiceType.cs:

public partial class ServiceType
{
    public ServiceType(ServiceTypeEnum @enum)
    {
        ID = (int) @enum;
        Name = @enum.ToString();
    }

    protected ServiceType() { } // For EF

    //[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ID { get; set; }

    [Required, MaxLength(100)]
    public string Name { get; set; }

    public virtual ICollection<ServiceProvider> ServiceProviders { get; set; }

    public static implicit operator ServiceType(ServiceTypeEnum @enum) => new ServiceType(@enum);

    public static implicit operator ServiceTypeEnum(ServiceType serviceType) => (ServiceTypeEnum) serviceType.ID;
}


public enum ServiceTypeEnum
{
    Ambulance = 1,
    [Display(Name = "Cash Advance")]
    CashAdvance = 2,
    Hospitalization = 3,
    Hotel = 4,
    [Display(Name = "House Call")]
    HouseCall = 5,
    [Display(Name = "Medical Escort")]
    MedicalEscort = 6,
    Transfer = 7,
    Repatriation = 8
}

ServiceProviderController.cs

public ActionResult Create()
    {
        var _allServiceTypes =  Enum.GetValues(typeof(ServiceTypeEnum))
           .Cast<ServiceTypeEnum>()
           .Select(t => new KeyValuePair<string, int>(t.ToString(), (int) t));

        var viewModel = new ServiceProviderViewModel.CreateModel()
        {
            AllServiceTypes = _allServiceTypes
        };

        return View(viewModel);
    }

    [HttpPost]
    public ActionResult Create(ServiceProviderViewModel.CreateModel viewModel)
    {
        if (ModelState.IsValid)
        {

            var serviceProvider = new ServiceProvider();
            serviceProvider.Title = viewModel.Title;            

            repository.InsertServiceProvider(serviceProvider);

            for (int i = 0; i < viewModel.SelectedServiceTypes.Length; i++)
            {
                var _serviceType = new ServiceType((ServiceTypeEnum)Enum.Parse(typeof(ServiceTypeEnum), viewModel.SelectedServiceTypes[i].ToString()));
                serviceProvider.ServiceTypes.Add(_serviceType);
            }

            repository.Save();

            return RedirectToAction("Index");
        }
        return View(viewModel);
    }

我不确定为什么数据库表ServiceTypeServiceProviders(由EF自动生成)没有填充正确的数据。什么都没有存储到它。通过在调试时查看serviceProvider对象,我可以看到一切似乎都很好(见下图)

enter image description here

我使用以下数据手动填充ServiceType表(与枚举匹配)

enter image description here

1 个答案:

答案 0 :(得分:0)

我假设您正在创建的“新”ServiceType对象,并且添加到ServiceProvider的关联是对手动插入ServiceType表而不是新对象的数据的引用...如果是这样,您将会或者想要从DbContext检索对象而不是创建新对象,或者您必须使用context.Set<ServiceType>.Attach(serviceType);context.Entry(serviceType).State = EntityState.Attached;将“新”ServiceType对象附加到当前DbContext。这些可能需要为ServiceType对象分配ID属性,以确保它正确映射到现有实体。这将确保您在插入时没有在ServiceType表中获得空ID或重复条目。

如果这不能解决问题,我们必须看看InsertServiceProvider的代码,以便更好地了解如何将ServiceProvider实体添加到DbContext