每个层次结构组的实体框架 4.2 表(按鉴别器)

发布于 2024-12-20 06:04:29 字数 1918 浏览 2 评论 0原文

我正在开发一个使用 EF 4.2 代码优先模型的项目。该模型包含产品的 TPH 继承结构。我需要在鉴别器上对该继承模型的多态结果进行分组,并且遇到了一些问题。

实体框架不会公开鉴别器来完成此分组。我的第一个问题是我可以直接访问这个鉴别器吗?我的阅读和经验告诉我不行,所以我想出了这个可行的解决方案。它的性能不佳,我对它的维护方式不满意。

我的类看起来像这样(简化):

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

我构建了一个扩展方法,它接受一个产品并将其基本类型名称作为字符串返回。

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

这样,我构建了这个结构来按类型对产品的结果进行分组,以便我可以遍历它们:

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

我现在可以循环遍历列表以获得我想要的行为,但性能并不理想,我担心它会是不可接受的随着产品数量的增加。

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

另外,这可以让我轻松访问共享属性(名称),但现在我没有太多选项可以将它们转换为真实类型,也许是围绕 TypeName 的选择案例。 。 。

感谢任何建议,也请原谅上面的任何代码错误,我凭记忆重新输入了示例,因为我目前无法访问该项目。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

木槿暧夏七纪年 2024-12-27 06:04:29

解决方案是进行更多建模,并创建一个具有属性 Name 的新实体 ProductType。那么 ProductProductType 之间就会有一个简单的 1-N 关系。我没有使用 EntityFramework,但使用 NHibernate,您可以轻松地使框架始终在查询时加入该表,这样它就不会返回 ProductType< 的代理/code> 对于每个 Product,这可能会损害性能。

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

A solution would be to model a bit more, and have a new entity ProductType having a property Name. Then you would have a simple 1-N relationship between Product and ProductType. I have not used EntityFramework, but with NHibernate you could easily make the framework always join that table on queries, so that it would not return a proxy for ProductType for each Product, which could harm performance.

As an add-on, in the future ProductType could develop other interesting properties (such as values that are common for every Product of that ProductType), so it adds flexibility to your solution, although it does have the immediate cost of adding another table to your database.

指尖凝香 2024-12-27 06:04:29

下面的 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()
}

Following Linq query should get you a way to solve group by discriminator

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()
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文