Reputation: 1250
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 (PAD_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
Upvotes: 0
Views: 737
Reputation: 385
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.
Upvotes: 2
Reputation: 93
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.
Upvotes: 0