2011-01-20 21 views
5

Używam NHibernate i mam problemy z tym zapytaniem ... Mam element klasy, który chcę pobrać przy użyciu jego identyfikatora. Wszystko w porządku. Jednak chcę również, aby właściwość bool w klasie Item miała wartość true, jeśli zostanie ustawiony inny warunek. W szczególności ta właściwość nosi nazwę IsMarked, informując, czy element jest oznaczony/patrzy/oznaczony dla użytkownika, który o to poprosił, i ta informacja jest ustawiona w tabeli, która podaje relację między przedmiotem a użytkownikiem.Ustawienie wartości na podstawie innej tabeli w kwerendzie NHibernate

Obecnie pobieram przedmiot, a następnie znajduję odniesienie - aktualizując właściwość na wartość true, jeśli można znaleźć odniesienie. Czy mogę to zrobić w jednym zapytaniu?

var item = Session.Get<Item>(itemId); 

var flaggedResult = Session.CreateCriteria<ItemWithUserFlag>() 
    .Add(Restrictions.Eq("User.Id", userId)) 
    .Add(Restrictions.Eq("Item", item)) 
    .List<ItemWithUserFlag>(); 

if (flaggedResult.Count > 0) 
    item.IsMarked = true; 

return item; 
+0

Jak twoje zajęcia odwzorowany? Czy istnieje wiele powiązań między użytkownikiem a przedmiotem? –

+0

Używam Fluent do mapowania. Istnieje relacja wiele do wielu reprezentowana w oddzielnej klasie ItemWithUserFlag. Użytkownik nie ma bezpośredniego związku z Przedmiotem, a Przedmiot nie ma bezpośredniego związku z Użytkownikiem. ItemWithUserFlag ma References ustawione na User i Item. – stiank81

Odpowiedz

7

Jak na temat korzystania formula wraz z filter w mapowaniu własności:

<property name="IsMarked" formula="(select count(*) from ItemWithUserFlag where ItemWithUserFlag.ItemId = ItemId and ItemWithUserFlag.UserId = :UserFilter.userId)" /> 

i filtr def:

<filter-def name="UserFilter"> 
    <filter-param name="userId" type="Int32"/> 
</filter-def> 

To spowoduje coś jak

SELECT Item.*, (select count(*) from ItemWithUserFlag where ItemWithUserFlag.ItemId = Item.ItemId and ItemWithUserFlag.UserId = ?) AS IsMarked FROM Item 

Dopóki IsMarked jest zdefiniowany jako bool, jeśli count(*) zwróci 0, zostanie przekonwertowany na false i jeśli cokolwiek będzie to > 0, zostanie przekonwertowany na true.

EDIT: Płynna reprezentacja

public class ItemMap : ClassMap<Item> 
{ 
    public ItemMap() 
    { 
     /// ... whatever 
     Map(x => x.IsMarked).Formula("(select count(*) from ItemWithUserFlag where ItemWithUserFlag.ItemId = ItemId and ItemWithUserFlag.UserId = :UserFilter.userId)"); 
    } 
} 

public class UserFilter : FilterDefinition 
{ 
    public UserFilter() 
    { 
     WithName("UserFilter") 
      .AddParameter("userId", NHibernate.NHibernateUtil.Int32); 
    } 
} 
+0

Thx! Nie testowałem jeszcze, ale brzmi, jakby to działało. Problem w moim przypadku polega na tym, że używam FluentNhibernate do mapowania. Nie wiem, czy mogę zdefiniować niektóre mapowania i xml w tym samym czasie, lub jeśli to samo można wyrazić w Fluent. Więc nie ma sposobu, aby osiągnąć to bezpośrednio w zapytaniu? – stiank81

+0

@ stiank81 Dodałem coś, co moim zdaniem powinno działać z Fluent. –

+0

@ stiank81 O osiągnięciu tego w zapytaniu: wierzę, że nie ma mowy. Logicznie rzecz biorąc, to, czego chcesz, nie jest ograniczeniem lub co, ale kolumną obliczeniową, więc myślę, że to musi być zrobione poprzez mapowania. Ale nie jestem takim ekspertem od nHibernate i dlatego nie mogę ci powiedzieć na pewno. –

Powiązane problemy