5

I am working on a project using an EF 4.2 code first model. This model contains a TPH inheritance structure for products. I need to group the polymorphic results of this inheritance model on the discriminator and am running into some issues.

The entity framework does not expose the discriminator to complete this grouping. My first question is can I get direct access to this discriminator? My reading and experience is telling me no, so I came up with this solution that sort of works. It is not performing well and I am not happy with how it will need to be maintained.

My classes look something like this (simplified):

Public MustInherit Class Product
      <key()>  
      Public Property ProductID as integer

      <StringLength(50, ErrorMessage:="Max 50 characters")>
      <Required(ErrorMessage:="Product name is required")>
      Public Property Name as String

      <TimeStamp()>
      Public Property Time_Stamp as DateTime = DateTime.Now()
End Class

Public Class Desktop
      Inherits Product

      <StringLength(50, ErrorMessage:="Max 50 characters")>
      <Required(ErrorMessage:="Processor is required")>
      Public Property Processor as String
End Class

Public Class Monitor
      Inherits Product

      <Required(ErrorMessage:="Monitor size is required")>
      Public Property Size_Inches as Integer
End Class

I built an extension method that takes a product and returns it's basetype name as a string.

<Extension()>
Public Function ProductType(ByVal inProduct as Product) as String
      ProductType = inProduct.GetType().BaseType.Name
End Function

With that, I built this structure to group the results of product by type so I can run through them:

Dim tmpProducts = db.Products.ToList()
Dim GrpProducts = tmpProducts.GroupBy(Function(prod) prod.ProductType) _
                             .Select(Function(s) New With {.ProductType = S.Key,
                                                           .Products = S })

I can now loop through the list to get the behavior I want, but the performance is not ideal and I am concerned it will be unacceptable as the number of products grows.

For Each ProductGroup in GrpProducts
       Dim TypeName as String = ProductGroup.ProductType
       Dim TypeProducts = ProductGroup.Products
Next

Also, this can give me easy access to shared properties (Name) but now I don't have many options to cast these into their real type, maybe a select case around TypeName. . .

Any recommendations are appreciated, also please forgive any code errors above, I retyped the examples from memory as I don't have access to the project at the moment.

4

2 回答 2

2

一个解决方案是进行更多建模,并拥有一个ProductType具有 property的新实体NameProduct那么你将在和之间建立一个简单的 1-N 关系ProductType。我没有使用EntityFramework,但是NHibernate您可以轻松地使框架始终在查询时加入该表,这样它就不会ProductType为 each返回代理Product,这可能会损害性能。

作为一个附加组件,将来ProductType可能会开发其他有趣的属性(例如每个属性都通用的值ProductProductType,因此它为您的解决方案增加了灵活性,尽管它确实有向您的数据库添加另一个表的直接成本。

于 2012-06-18T15:10:10.807 回答
1

遵循 Linq 查询应该可以让您通过鉴别器解决分组问题

from a in db.Records
group a.ID by new
{
    Name= a is Audio ? "Audio" :
            a is Video ? "Video" :
            a is Picture ? "Picture" :
            a is Document ? "Document" : "File"
} into g
select new 
{
    Name = g.Key.Name,
    Total = g.Count()
}
于 2016-10-12T07:32:16.073 回答