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.
精彩评论