2011-02-15 84 views
0

我有一个抽象类Contact使EF 4成为MustOverride(抽象)成员?

这导致两个子类:

  1. 公司(标题)
  2. 人(名字,姓氏)

我想Person表中添加一个计算的 '标题' 山坳,返回FirstName +''+ LastName,这会给我更好的搜索选项。

所以我要创建的联系表有一个抽象属性名称,每个这两个工具的,所以,我将能够使用:

Dim contacts = From c In context.Contacts 
       Where c.Title.Contains("Nash") 

我敢肯定这是不可能的,问题是什么是有效的替代方法?

在我的情况我有一个显示所有联系人Company和人类型一个ListBox,我有一个搜索文本框,我想服务查询(GetContacts(searchQuery As String))查询过滤设置对DB。

更新
威尔的回答后,我决定在Person表如上创建一个计算山坳。 的问题是什么什么是imlpement的WCF的RIA查询方法最有效的方法:

Public Function GetContacts(searchQuery As String) As IQueryable(Of Contact) 
    'Do here whatever it takes to retieve from Contacts + People 
    'and mix the results of both tables ordered by Title 
End Function 

回答

2

不幸的是,尽管有一种方法与partial classes做到这一点,我99%肯定你不能混用LINQ查询触摸实体属性和部分类中定义的“POCO”属性。

Linq to Entity上下文实际上会将这些查询转换为sql,并且它无法处理上下文不直接支持特定方法的情况。 L2E的一个常见示例是无法在查询中使用枚举。就像知道如何处理枚举一样,上下文在转换为raw sql时肯定不知道如何处理POCO属性。

您可能想要调查的选项是在数据库中创建计算列或运行查询,执行传统的ToArray()以触发枚举,然后检查内存中的计算列。但是,这可能不是一个好的解决方案,具体取决于表格的大小。因此,基本上,您希望搜索两种不同的类型(由两个不同的表格支持),然后将结果合并显示给用户。我不得不说,多态不是最好的解决方案。在UI中展示它们的愿望不应该强迫设计决定一直贯穿到你的类型定义中。

我在WPF中做过几次类似的事情。我已经完成了两种方法;通过使用包装模型的外观类型的形式,并且可以通过一个公共基类型处理多态,并将集合中的所有不同类型视为System.Object。

当需要类型安全性和以相同方式处理不同类型的能力时,第一种方法是可以的。这些包装扩展了一个公共基类,并被编码为“知道”如何正确处理每个包装类型。

当你不需要类型安全性时,第二种方法是可以的,比如将一个集合暴露给一个WPF视图时,你在一个ItemsControl中显示它们,它可以找出正确的DataTemplate类型集合中的每个实例。

我不确定哪种方式最适合您,但无论哪种方式,您都应该分别查询公司和个人表,Union两个结果集,然后对其进行适当的排序。

伪代码:

//Wrapper version 
var results = Company 
       .Where(x=>x.Title.Contains(searchTerm)) 
       .Select(x=> new CompanyWrapper(x)) 
       Cast<BaseWrapper>().Union(
        Person 
         .Where(x=>x.ComputedTitle.Contains(searchTerm)) 
         .Select(x=> new PersonWrapper(x)) 
         .Cast<BaseWrapper>()); 

//System.Object version 
var results = Company 
       .Where(x=>x.Title.Contains(searchTerm)) 
       Cast<object>().Union(
        Person 
         .Where(x=>x.ComputedTitle.Contains(searchTerm)) 
         .Cast<object>()); 

在这两种情况下,你可能有专门垂头丧气。再一次,如果你需要在UI中使用它,第一种可以提供安全类型,第二种更简单,后端需要的代码更少,但只有在用户界面中不需要类型安全时才有用。

至于排序,一旦你搜索并结合了你的结果,你可以OrderBy排序结果,但是你将不得不提供一个函数来执行排序。此功能根据您选择的版本而有所不同。

+1

+1 @ will:100%肯定 - 部分类的属性不能在Linq-to-entities查询中使用。标题列必须以某种方式在DB中准备 - 我建议查看。 – 2011-02-15 09:06:50