正在为每个产品创建创建重复的DataType

时间:2013-06-18 10:18:56

标签: c# asp.net entity-framework asp.net-mvc-4

我有一个产品型号,允许用户为其产品定义自己的自定义字段。这是通过3个表/模型来完成的。 Product模型,其中包含CustomProductProperty模型的IEnumerable枚举。每个CustomProductPropertyModel中都是DataType模型的外键。此DataType模型是用户定义可用字段的位置。

我遇到的问题是,每次用户创建新产品时,都会创建一组新的DataType。如何处理数据,以便CustomProductProperty指向现有DataType而不创建新数据?

[Table("Product")]
public class Product
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductID { get; set; }
    public int ProductTypeID { get; set; }
    [Display(Name = "Product Name")]
    public string ProductName { get; set; }
    [ForeignKey("ProductTypeID")]
    [Display(Name = "Product Type")]
    public virtual ProductType ProductType { get; set; }
    public virtual ICollection<CustomProductProperty> CustomProperties { get; set; } 
}

[Table("CustomProductProperty")]
public class CustomProductProperty
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CustomPropertyID { get; set; }

    public int CustomDataTypeID { get; set; }
    [ForeignKey("CustomDataTypeID")]
    public CustomDataType DataType { get; set; }

    public int ProductID { get; set; }
    [ForeignKey("ProductID")]
    public virtual Product Product { get; set; }

    public string PropertyValue { get; set; }
}

[Table("CustomDataType")]
public class CustomDataType
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CustomTypeID { get; set; }
    public string PropertyName { get; set; }
    public CustomDataTypes DataType { get; set; }
    public int ModuleID { get; set; }
    [ForeignKey("ModuleID")]
    public Module Module { get; set; }
}

在创建表单中,我为@Html.HiddenFor()添加了DataType.CustomTypeID,在调试时,它包括在内但是当我添加到我的dbcontext时,它会创建一个全新的DataType

if (ModelState.IsValid)
    {
        db.Products.Add(productViewModel.Product);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

编辑:创建产品的表格如下。

<table class="basic_info_tbl">
    <tr>
        <th>@Html.LabelFor(model => model.Product.ProductName):</th>
        <td>@Html.TextBoxFor(model => model.Product.ProductName) </td>
        <th>@Html.LabelFor(model => model.Product.ProductType):</th>
        <td>@Html.DropDownListFor(model => model.Product.ProductTypeID, Model.ProductTypes)</td>
        @Html.EditorFor(model => model.Product.CustomProperties)
    </tr>
</table>

使用编辑器模板:

<tr>
        @Html.HiddenFor(model => model.DataType.CustomTypeID)
    <th>@Model.DataType.PropertyName</th>
    <td>@Html.TextBoxFor(model => model.PropertyValue)</td>
</tr>

1 个答案:

答案 0 :(得分:1)

来自Lerman&amp;米勒的书 DbContext

  

添加图表的根将导致每个实体   要将上下文注册为新实体的图形。这种行为是一样的   如果您使用DbSet.Add或将实体的State属性更改为Added。一切都结束了   实体由州经理跟踪,您可以然后按照图表的方式工作,   为每个实体指定正确的状态。

(我的重点)

因此,在db.Products.Add(productViewModel.Product)之后,对象图中的CustomDataType个对象也是Added

Add()之后你应该遍历对象图

foreach (var dt in productViewModel.Product.CustomProperties
                                   .Select(x => x.DataType).ToList())
{
    Entry(dt).State = EntityState.Unchanged;
}