2011-11-16 52 views
3

我試圖做到這一點:屬性選擇和地點<T>查詢使用LINQ

public class SomeEntityClass 
{ 
    public Guid MyClassProperty {get;set;} 
} 

public class AnotherEntityClass 
{ 
    public Guid AnotherProperty {get;set;} 
} 

public T GetByProperty<T>(Guid value, Expression<Func<T, object>> selector) 
{ 
    return = Session.Query<T>().Where(x => selector == value).FirstOrDefault(); 
} 

應該叫:

Repository.GetByProperty<SomeEntityClass>(Guid.NewGuid(), x => x.MyClassProperty); 
Repository.GetByProperty<AnotherEntityClass>(Guid.NewGuid(), x => x.AnotherProperty); 

,但它不工作。

任何幫助?

謝謝。

+0

不應該''對象'是'Guid'因爲你想要一個返回'Guid'的方法嗎? –

+0

爲什麼不使用'x => x.MyClassId == Guid.NewGuid()'? – hazzik

+1

說「不起作用」不如說什麼不起作用(錯誤消息/示例意外結果)。 –

回答

7

嘗試使用類似的東西:

public T GetByProperty<T, TValue>(TValue value, Expression<Func<T, TValue>> selector) { 
    var predicate = Expression.Lambda<Func<T, bool>>(
     Expression.Equal(selector.Body, Expression.Constant(value)), 
     selector.Parameters 
    ); 

    return Session.Query<T>().Where(predicate).FirstOrDefault(); 
} 
+0

Equal的簽名是Equal(Expression left,Expression right);所以它不適用於「值」作爲第二個參數 –

+0

固定爲'Expression.Constant(值)' – hazzik

+0

它的工作原理!謝謝。 –

0

您需要調用對象的選擇,所以這樣的事情應該工作

public T GetById<T>(Guid id, Func<T, object> idSelector) 
{ 
    return Session.Query<T>().Where(x => idSelector(x) == id).FirstOrDefault(); 
} 

,而不是Where/First(OrDefault)組合此外,在類似情況下,我通常使用Single(OrDefault)因爲我喜歡一個例外如果某處存在重複密鑰,則會被拋出。

+0

它不起作用,並會導致全表加載。 – hazzik

+0

這是連接到什麼樣的ORM?我一直在使用與EntityFramework(CodeFirst)類似的模式,它的效果很好。 – SWeko

+0

到任何ORM。因爲它會回落到linq-to-objects – hazzik

0

到SWeko的答案類似,另一種讓你鍵入idSelector(防止Object比較,Guid ...)

public T GetById<T, TKey>(TKey id, Func<T, TKey> idSelector) 
{ 
    return Session.Query<T>().FirstOrDefault(x => idSelector(x) == id); 
} 

你可以稱之爲類似...

var result = GetById(guidId, (AnotherEntityClass x) => x.MyClassId); 

更多過,如果添加了下面的類...

public class YetAnotherEntityClass 
{ 
    public long MyId {get;set} 
} 

你仍然可以使用同樣的方法...

var result = GetById(12345, (YetAnotherEntityClass x) x=> x.MyId; 

如果你發現這並不全表負荷,考慮以下情況:

public T GetFirstByCriterion<T, bool>(Expression<Func<T, bool>> criterion) 
{ 
    return Session.Query<T>().FirstOrDefault(criterion); 
} 

其可與

被稱爲
var result = GetFirstByCriterion((AnotherEntityClass x) x => x.AnotherProprty = guidId); 
+0

它甚至沒有編譯 – hazzik

+0

公平的一個,錯誤從OP中複製並且表達式未被編譯...更正 – Smudge202