开发者

Asp.net Dynamic Data 4 One-to-One ForeignKey.ascx Returning Primary Key

开发者 https://www.devze.com 2023-03-22 14:57 出处:网络
I have a Dynamic Data 4 site using LinqToSql (.dbml) for 2 tables with a one-to-one relationship. One table (child) does not always have a row corresponding to the primary table.

I have a Dynamic Data 4 site using LinqToSql (.dbml) for 2 tables with a one-to-one relationship. One table (child) does not always have a row corresponding to the primary table.

Whenever that is the case (no child table row) instead of an empty row cell the DD ForeignKey.ascx Field template is displaying a link to:

Childtable/Detail.aspx?ChildPkField=PRIMARYTABLEGUID

I can't find any combination of SQL F-key setups and/or .dbml column property settings that prevent this. The only solution so far is a Custom ForeignKey.ascx template with

 protected string GetDisplayString()
    {
        object value = FieldValue;
        if (value == null)
        {
            //replace this
            //return FormatFieldValue(ForeignKeyColumn.GetForeignKeyString(Row));
            //with this
            return "";
        }
        else
        {
            return FormatFieldValue(ForeignKeyColumn.ParentTable.GetDisplayString(value));
        }
    }

Obviously not an optimal solution. To simplify I have removed all Custom Metadata for both tables and all other relationships the tables were involved in. No change.

I am sure it i something simple but I have looked at it for too long now - any help appreciated!

Here are the current Create Table Scripts from Sql Manager:

CREATE TABLE [dbo].[UserProfile](
[UserId] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
[ProfileUserName] [nvarchar](50) NOT NULL,
      CONSTRAINT [PK_Profile] PRIMARY KEY CLUSTERED ([UserId] ASC )WITH (PA开发者_如何学JAVAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
 GO
 ALTER TABLE [dbo].[UserProfile] ADD  CONSTRAINT [DF_Profile_UserID]  DEFAULT (newid()) FOR [UserId]
GO

and

CREATE TABLE [dbo].[SubscribedUser](
[subUserId] [uniqueidentifier] NOT NULL,
[subExpireDate] [date] NULL,
     CONSTRAINT [PK_SubscribedUsers] PRIMARY KEY CLUSTERED ([subUserId] ASC) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY]
 GO
ALTER TABLE [dbo].[SubscribedUser]  WITH CHECK ADD  CONSTRAINT [FK_SubscribedUser_UserProfile] FOREIGN KEY([subUserId]) REFERENCES [dbo].[UserProfile] ([UserId])
GO
ALTER TABLE [dbo].[SubscribedUser] CHECK CONSTRAINT [FK_SubscribedUser_UserProfile]
GO


In fact, the first method you used is perhaps the most optimal solution as the query has already been made on the server-side to determine whether the column data matches the foreign key relationship. No more querying is needed, just test FieldValue == null. Besides, the template controls are there to be edited, which is why they're not compiled to assemblies:

protected string GetDisplayString()
{
    object value = FieldValue;
    if (value == null)
    {
        //replace this
        //return FormatFieldValue(ForeignKeyColumn.GetForeignKeyString(Row));
        //with this
        return "";
    }
    else
    {
        return FormatFieldValue(ForeignKeyColumn.ParentTable.GetDisplayString(value));
    }
}

However, if you intend to preserved the value of the source field, use this method instead:

protected string GetNavigateUrl()
{
    //replace this
    //if (!AllowNavigation)
    //with this
    if (!AllowNavigation || FieldValue == null)
    {
        return null;
    }
    if (String.IsNullOrEmpty(NavigateUrl))
    {
        return ForeignKeyPath;
    }
    else
    {
        return BuildForeignKeyPath(NavigateUrl);
    }
}

Under certain conditions (including the default css styles), it will generate a hyperlink-looking field that cannot be clicked. You can use jQuery to filter and remove those false hyperlinks by setting their outerHTML as their innerHTML (client-side scripting). Of course, there are more elegant methods like adding a <asp:label> to the ForeignKey.ascx and switching to that control when needed.

Note: this method works when using ADO.NET Entity Data Model. I didn't try it on LinqToSqlClasses.


Have you tried to remove both tables from the linq2sql class and then readd them again? Maybe recreating the relation again in the schema even before that?

F.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号