【问题标题】:Incorrect generated URL for "view .." link. ASP.NET Dynamic data为“view ..”链接生成的 URL 不正确。 ASP.NET 动态数据
【发布时间】:2015-01-23 05:56:00
【问题描述】:

我被困在棘手的情况下,我在集成 ASP.NET 动态数据 + EF6 时遇到过

我有几张桌子: Products -> ProductSales,映射为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 将构建“view productsales” 有链接

/ProductSales/List.aspx?Product.Id=1 - 我认为这是不正确的。

我尝试使用 url 并发现 /ProductSales/List.aspx?Id=1 - 它有效。

更新:我遇到了错误:

DataBinding:“System.Web.DynamicData.Util.DictionaryCustomTypeDescriptor”不包含名为“Product”的属性。 说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。 异常详细信息:System.Web.HttpException:DataBinding:“System.Web.DynamicData.Util.DictionaryCustomTypeDescriptor”不包含名为“Product”的属性。

我知道我可以去 ChildrenField 模板并使用 ChildrenPath 做一些 hack 魔术,但希望从社区获得甜蜜和清晰的解决方案,提前致谢。

【问题讨论】:

  • 我不知道这是否有帮助,但看起来动态数据正在创建一个视图,其顶层是 Prodcut,并且您正在显示该产品的所有 ProductSales。跨度>

标签: c# asp.net entity-framework asp.net-dynamic-data


【解决方案1】:

这将通过修改您的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 处理简单的情况(DD EF6 失败!,当找不到值时使用原始代码)。

【讨论】:

  • 我得到一个 Misc.ChangeType 由于其保护级别错误而无法访问。将其更改为返回(字符串)值;
  • 这个超级好用,谢谢!!!是否有更好的解释来解释为什么最初我可以理解它?是动态数据中的错误还是我的数据源设置不正确?
  • 这是 EntityDataSource 中的一个错误。我很确定其他数据源不会发生这种情况。不过,我已经有一段时间没有通过它了。
  • 我得到一个“杂项”由于其保护级别而无法访问(在导入 Utils... 之后)。我正在尝试这个.. return (DataBinder.GetPropertyValue(Row, foreignKeyName)).ToString();
【解决方案2】:

好的,我花了几天时间阅读寻找答案,终于找到了。

我很伤心,我正在使用 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; }
}

不需要像我之前那样添加 Identity 选项作为属性(参见原始问题)。

默认情况下,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?ProductId=1

我的头在上面吹着,但终于解决了,希望它能帮助你节省时间。谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 2012-02-24
    • 1970-01-01
    • 2011-07-17
    • 2015-05-23
    相关资源
    最近更新 更多