将动态属性添加到模型中

时间:2013-04-11 12:05:45

标签: asp.net-mvc entity-framework design-patterns

我无法解决这个问题,但还没找到正确的搜索键:

我希望有categoriesitems items,其中attributes具有特定attributes。那些category(文本字段,下拉列表或复选框)应添加到attributes,我想为每个item编辑并保存TextDropdown

我正在使用MVC 4和代码优先的EF5。我该如何实现呢?

我的第一种方法是几个类,如AttributeCategory,它们是从一个抽象的public class Category { [Key] public int CategoryId { get; set; } public string Name { get; set; } public string Description { get; set; } public virtual ICollection<Item> Items { get; set; } public virtual ICollection<Attribute> Attributes { get; set; } } 类和一个item类继承而来的:

category

但后来我不知道要继续。我是正确的方式还是完全错误的?有人可以给我一些我可以搜索的提示吗?

修改

最终我正在尝试建立一个高保真设备列表。扬声器具有与放大器不同的属性,并且具有与录音机不同的属性。我想统一查看每个设备的详细信息,并预先定义该类别的特定属性,并附加一个免费的文本区域。扬声器XYZ是我的attribute,扬声器{{1}}和dB {{1}}。

3 个答案:

答案 0 :(得分:1)

我实际上从未使用过代码优先方法,但我可以让您对如何处理此方案有所了解......对我来说,它看起来Item是主要的而不是{{1} }。所以你可以拥有这种结构......

Category

希望这会有所帮助..

答案 1 :(得分:1)

好的,所以这个问题基本上是关于数据设计的。

首先,我假设规则是:

  1. 一个项目有一个类别
  2. 一个类别有很多属性
  3. 一个项目具有与类别相关联的许多属性
  4. 对于规则1,它在您的设计中足够好。 (简化示例)

    public class Category{
      public IEnumerable<Item> Items{get;set;}
    }
    public class Item{
      public Category Category{get;set;}
    }
    

    很清楚。

    对于规则2,我认为你应该创建一个CategoryAttribute类。它保存了一个到多个类别和属性之间的关系。基本上,CategoryAttribute是master,而子类是ItemAttribute。

    public class Category{
      public IEnumerable<CategoryAttribute> CategoryAttributes{get;set;}
    }
    public class CategoryAttribute{
      public Category Category{get;set;}
      public string CategoryName{get;set;}
      public string DefaultValue{get;set;} // maybe a default value for specific 
                                           // attribute, but it's up to you
    
      public IEnumerable<ItemAttribute> ItemAttributes{get;set;}
    }
    

    IEnumerable<ItemAttribute>是类别属性和项目属性之间的一对多关系。

    对于规则3,规则2中描述的ItemAttribute将表示属于每个项目的属性。

    public class Item{
      public IEnumerable<ItemAttribute> ItemAttributes{get;set;}
    }
    public class ItemAttribute{
      public Item Item {get;set;} // it owned by one attribute
      public CategoryAttribute{get;set;} // it owned by one category attribute
    }
    

    我不太清楚如何首先在代码中表示关系或主键和外键。希望如果需要我可以提高我的答案(如果我能的话)。但希望我的关于每个对象的关系和类设计的插图。

答案 2 :(得分:1)

我觉得这样的事情对你有用......

public class Category
{
    public int CategoryId { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }

    public virtual ICollection<Item> Items { get; set; }
    public virtual ICollection<Attribute> Attributes { get; set; }
}

public class Item
{
    public int ItemId { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }

    public int CategoryId { get; set; }
    public Category Category { get; set; }
    public virtual ICollection<ItemAttribute> ItemAttributes { get; set; }
}

public class Attribute
{
    public int AttributeId { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }

    public virtual ICollection<Category> Categories { get; set; }
    public virtual ICollection<ItemAttribute> ItemAttributes { get; set; }
}

public class ItemAttribute
{
    public int ItemId { get; set; }
    public int AttributeId { get; set; }

    public Item Item { get; set; }
    public Attribute Attribute { get; set; }

    public string Value { get; set; }
    public int ValueInt{ get; set; }
    // etc. 
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<ItemAttribute>()
        .HasKey(x => new { x.ItemId, x.AttributeId });
    modelBuilder.Entity<ItemAttribute>()
        .HasRequired(x => x.Item)
        .WithMany(x => x.ItemAttributes)
        .HasForeignKey(x => x.ItemId)
        .WillCascadeOnDelete(false);
    modelBuilder.Entity<ItemAttribute>()
        .HasRequired(x => x.Attribute)
        .WithMany(x => x.ItemAttributes)
        .HasForeignKey(x => x.AttributeId)
        .WillCascadeOnDelete(false);
    // AttributeCategories is created for you - but you can do the same as ^ above to customize
    // just change 'ICollection<Category> Categories' to collection of 'ItemAttribute'
}

// use it like e.g.
var item = new Item { Name = "ItemTest", };
var attribute = new Attribute { Name = "attributeTest", };
item.ItemAttributes = new List<ItemAttribute> 
{
    new ItemAttribute { Item = item, Attribute = attribute, Value = "test", },
};
var category = new Category
{
    Name = "cat1",
    Items = new[]
    {
        item,
        new Item{ Name = "Item1", },
        new Item{ Name = "Item2", },
        new Item{ Name = "Item3", },
        new Item{ Name = "Item4", },
        new Item{ Name = "Item5", },
    },
    Attributes = new[]
    {
        attribute,
        new Attribute{ Name = "att1", },
        new Attribute{ Name = "att2", },
    }
};
db.Categories.Add(category);
db.SaveChanges();
var categories = db.Categories.ToList();

ItemAttribute用于连接和存储values

您需要根据自己的要求进一步调整。