Can a LINQ to SQL IsDiscriminator column NOT inher

2020-04-14 08:51发布

问题:

I'm designing my database and LINQ To SQL ASP.NET web application.

Imagine I have two types of pages: normal and root. Some pages are roots. Some pages are not.

I have a Page database table and a RootPage database table:

      Page
      ----
   PK PageId
      HtmlTitle
      PageHeading
      MetaDescription
      IsRoot

      RootPage
      --------
FK PK PageId
      FavIcon
      StyleSheet
      MasterPage

I think that if within my DBML file I set the IsDiscriminator property of the IsRoot column, then my RootPage class will inherit the Page class.

I want to be able to work like this in my code:

MyDataContext db = new MyDataContext();

var roots = from p in db.Pages
            where p is RootPage
            select (RootPage)p;

Or like this:

RootPage r = new RootPage();
r.HtmlTitle = "Foo";
r.FavIcon = "bar.ico";
...
db.Pages.Add(r);
db.SubmitChanges();

Can a LINQ to SQL IsDiscriminator column be nullable or false? Will this work?

回答1:

The problem here is that you are trying to split your class between two tables, RootPage and Page.

Unfortunately LINQ to SQL only supports single table inheritence so this would not work.

You would need to merge the two table definitions together and make the RootPage-specific fields nullable. e.g.

   Page
   ----
PK PageId
   HtmlTitle
   PageHeading
   MetaDescription
   IsRoot
   FavIcon (Nullable)
   StyleSheet (Nullable)
   MasterPage (Nullable)

You would then set IsRoot to be the discriminator and mark the Page class as the default type and RootPage as being the class for the discriminator value of 'True'.

An alternative if you didn't mind things being read only would be to make a view that joined the two tables together and base the classes off that.

A third option might be to consider composition such as renaming the RootPage table to Root and creating an association between RootPage and Root. This would mean that instead of your RootPage class having all those properties it would instead only expose the Root property where they actually reside.