我遇到了一个棘手的问题,当集成ASP.NET动态数据+EF6 时
我有几张桌子:产品->产品销售,映射为1-MANY
数据库是使用EF CF方法创建的。
Init架构中的某种代码。
CreateTable(
"dbo.ProductSales",
c => new
{
Id = c.Long(nullable: false, identity: true),
IsActive = c.Boolean(nullable: false),
Price = c.Int(nullable: false),
Description = c.String(),
Name = c.String(nullable: false),
Product_Id = c.Long(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Products", t => t.Product_Id)
.Index(t => t.Product_Id);
CreateTable(
"dbo.Products",
c => new
{
Id = c.Long(nullable: false, identity: true),
Description = c.String(),
IsNew = c.Boolean(nullable: false),
Discount = c.Int(nullable: false),
IsActive = c.Boolean(nullable: false),
Name = c.String(nullable: false),
Category_Id = c.Long(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Categories", t => t.Category_Id, cascadeDelete: true)
.Index(t => t.Category_Id);
DTOS:
public class Product : Entity
{
public string Description { get; set; }
public bool IsNew { get; set; }
public int Discount { get; set; }
[DefaultValue(true)]
public bool IsActive { get; set; }
public virtual ICollection<ProductSale> Sales { get; set; }
[Required]
public virtual Category Category { get; set; }
public virtual ICollection<Photo> PhotoCollection { get; set; }
public virtual ICollection<Shop> Shops { get; set; }
}
public class ProductSale : Entity
{
public bool IsActive { get; set; }
public int Price { get; set; }
public string Description { get; set; }
public virtual ICollection<Photo> PhotoCollection { get; set; }
public virtual Product Product { get; set; }
}
public class Entity
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
}
应用程序大多运行良好。但有一个烦人的问题。对于案例1-MANY,如上所述,DD将构建">查看产品销售"带有链接
/ProductSales/List.aspx产品Id=1-我认为这是不正确的。
我尝试过使用url,发现/ProductSales/List.aspxId=1-它有效。
更新:我有错误:
DataBinding:"System.Web.DynamicData.Util.DictionaryCustomTypeDescriptor"不包含名为"Product"的属性。描述:在执行当前web请求期间发生未处理的异常。请查看堆栈跟踪以了解有关错误以及错误在代码中的来源的更多信息。异常详细信息:System.Web.HttpException:DataBinding:"System.Web.DynamicData.Util.DictionaryCustomTypeDescriptor"不包含名为"Product"的属性
我知道我可以去ChildrenField模板,用ChildrenPath做一些破解魔法,但希望能从社区获得甜蜜而清晰的解决方案,提前谢谢。
这将通过修改ForeignKey.ascx.cs
:来永久解决此问题
将Page_Init
替换为:
protected void Page_Init(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// Set the initial value if there is one
string initialValue = AltDefaultValue ?? DefaultValue;
if (!String.IsNullOrEmpty(initialValue))
DropDownList1.SelectedValue = initialValue;
}
}
private string AltDefaultValue
{
get
{
var foreignKeyNames = Column.ForeignKeyNames;
if (foreignKeyNames.Count != 1) return null;
object value;
if (DefaultValues.TryGetValue(foreignKeyNames.Single(), out value))
return Misc.ChangeType<string>(value);
return null;
}
}
同时修改您的ForeignKey_Edit.ascx
:
将OnDataBinding
替换为:
public string AltGetSelectedValueString()
{
MetaForeignKeyColumn column = (MetaForeignKeyColumn)Column;
foreach (string foreignKeyName in column.ForeignKeyNames)
return Misc.ChangeType<string>(DataBinder.GetPropertyValue(Row, foreignKeyName));
return null;
}
protected override void OnDataBinding(EventArgs e) {
base.OnDataBinding(e);
string selectedValueString = AltGetSelectedValueString();
ListItem item = DropDownList1.Items.FindByValue(selectedValueString);
if (item != null) {
DropDownList1.SelectedValue = selectedValueString;
}
}
一旦完成,它将对简单情况使用AltDefaultValue
(在这种情况下,DDEF6失败!并且在找不到值时使用原始代码)。
好吧,我花了几天时间阅读寻找答案,终于找到了。
我很难过,我正在使用EF CF方法。
InitialSchema的生成在CF中是一件棘手的事情。
我对我的POCO类进行了一些更改:
public class Product : Entity
{
public string Description { get; set; }
public bool IsNew { get; set; }
public int Discount { get; set; }
[DefaultValue(true)]
public bool IsActive { get; set; }
[Required]
public string Name { get; set; }
public int CategoryId { get; set; }
[Required]
public virtual Category Category { get; set; }
public virtual ICollection<Photo> Photos { get; set; }
public virtual ICollection<Shop> Shops { get; set; }
public virtual ICollection<Sale> Sales { get; set; }
}
public class Sale : Entity
{
public bool IsActive { get; set; }
public int Price { get; set; }
public string Description { get; set; }
[Required]
public string Name { get; set; }
public int ProductId { get; set; } <-- added FK
public virtual Product Product { get; set; }
public virtual ICollection<Photo> Photos { get; set; }
}
EF CF足够聪明,能够理解依赖关系并建立适当的关系,我们的目标只是帮助CF正确地做到这一点。
- CF使用命名约定FK=/TableName here/Id
- 不在乎如何写Id,Id,Id-CF会忽略大小写
- 我为我拥有的每个实体、CategoryId等添加了明确的FK
这还不够,下一点:我有实体类,现在很简单:
public class Entity
{
// no attr here.
public int Id { get; set; }
}
不需要添加"标识"选项作为属性,就像我之前在中所做的那样(请参阅来源问题)。
默认情况下,CF使用约定并将Id视为密钥。
因此,我已经使用重建了我的初始模式
Enable-Migrations -ProjectName "MyProject"; add-migration InitialSchema -ProjectName "MyProject.Contracts"
然后
Update-Database -ProjectName "MyProject.Contracts" -StartUpProjectName "MyProject.Web" -ConnectionStringName "MyProjectContext"
因此,我有了一对多的正确URL
/Sales/List.aspx产品Id=1
我的头在上面乱转,但最终它解决了,希望它能帮助你节省时间。感谢