2011-05-28 21 views
1

我有一個Linq表達式,它在對象列表上運行,在使用它之前,需要對其中一個對象屬性進行類型檢查。Linq類型檢查3次 - 有更好的形狀嗎?

例子:

IEnumerable<Employee> activeAuditOwners = (

    from objectStateEntry in objectStateEntries 
    where (objectStateEntry.Entity is IAuditEntity) == true 
     && (objectStateEntry.Entity as IAuditEntity).Active == true 
    select (objectStateEntry.Entity as IAuditEntity).Owner 

); 

我擔心的是我使用的類型檢查的3倍(是,如,AS)不覺得很乾。

這個查詢有沒有更好的形狀來避免這種情況(沒有創建第二個查詢)?

更新:感謝您的好回答,我爲未來的讀者整理了一下這個例子。

回答

1

的一種方法是使用let子句:

所有的
from auditObjectStateEntry in auditObjectStateEntries 
let entity = auditObjectStateEntries.Entity as IAuditEntity 
where entity != null 
    && entity.Active 
select entity.Owner 
3

什麼OfType擴展方法:

var data = from a in auditObjectStateEntries.OfType<IAuditEntity>() 
      where a.Active 
      select a.Owner; 

編輯:

我忽略.Entity一部分,所以正確的查詢是:

var data = from e in auditObjectStateEntries.Select(a => a.Entity).OfType<IAuditEntity>() 
      where e.Active 
      select e.Owner; 
+0

對不起拉迪斯拉夫,我的例子是誤導 - 我已經更新了它。我不知道objectStateEntry.Entity的類型是什麼 - 初始集合不是問題。 – Jamie 2011-05-28 14:48:31

+0

他想過濾「實體」屬性,而不是集合本身。 – svick 2011-05-28 14:50:13

+0

啊,是的,實際上OfType更好。在那裏忘了一秒鐘。絕對比我的建議更清潔! +1 – 2011-05-28 14:50:47

0

是的,你可以使用let表達式:

from auditObjectStateEntry in auditObjectStateEntries 
let auditEntity = auditObjectStateEntry.Entity as IAuditEntry 
where auditEntity != null 
      && 
     auditEntry.Active 
select auditEntry 

更新: 我忘記了OfType<T>正如其他回答者所建議的。絕對是一個更清潔的解決方案,所以建議使用這種方法。

0

首先,你可以忘記is,你不需要它。每this documentation

expression as type 

等同於:

IEnumerable<Employee> activeAuditOwners = (
    from auditObjectStateEntry in auditObjectStateEntries 
    let entity = auditObjectStateEntry.Entity as IAuditEntry 
    where entity != null && auditEntry.Active 
    select auditEntry.Owner 
); 
+0

我不明白,你不需要'as',那麼讓我們使用它? – svick 2011-05-28 18:22:09

+0

oi,對不起...不需要用。 – Kon 2011-05-29 11:51:12

2

有一些不錯的:

expression is type ? (type)expression : (type)null 

所以,你可以通過使用一個轉換的嘗試,或許是這樣的簡化代碼解決方案在這裏,但我會使用這樣的OfType

IEnumerable<Employee> activeAuditOwners = objectStateEntries 
    .Select(s => s.Entity) 
    .OfType<IAuditEntry>() 
    ,Where(e => e.Active) 
    .Select(e => e.Owner);