Pergunta

I am new to NHibernate and WCF and trying to wrap my head around a few concepts, namely how to update a record without having to load/query first.

I have written two WCF methods for use by a GUI client.

Some prelim info:

public class Users  // Corresponding to SQL table Users
{
    public virtual int UserId { get; set; }     // internal autogenerated ID
    public virtual string UserName { get; set; }
}

public class UserWorklistPreference // Corresponding to SQL table UserWorklistPreference    
{
    public virtual int UserWorklistPreferenceID { get; set; } // internal autogenerated ID
    public virtual int AutoRefreshPeriod { get; set; }
    public virtual Users UserOfPreference { get; set; } // "foreign key" via Users entity class 

}


public class UsersMap : ClassMap<Users>
{
    public UsersMap()
    {
        Id(x => x.UserId);
        Map(x => x.UserName);
    }
}

public class UserWorklistPreferenceMap : ClassMap<UserWorklistPreference>
{
    public UserWorklistPreferenceMap()
    {
        Id(x => x.UserWorklistPreferenceID);
        Map(x => x.AutoRefreshPeriod);
        References(x => x.UserOfPreference)
            .Column("UserId")
            .Cascade.All();     // Not sure if Cascade is needed in my situation.
    }
}

SQL Server Table Users:
 UsersId
 UserName

SQL Server Table UserWorklistPreference:
 UserWorklistPreferenceID 
 AutoRefreshPeriod 
 UserID (FK)

The GUI displays the logged-in user's autorefresh setting by making a call to:

public SomeDataTransferObj GetUserWorkspacePreferences(int iD) // where iD is the internal identifier of the logged-in user.

public SomeDataTransferObj GetUserWorkspacePreferences(int iD)
{
// method basically does this (ignoring session factory/session/transaction/wcf context logic for now):

    var result =
        (from prefs in Session.Query<UserWorklistPreference>()
        where prefs.UserOfPreference.UserId == iD
        select prefs).SingleOrDefault();


    return new SomeDataTransferObj
            {
                UserId = result.UserOfPreference.UserId,
                UserName = result.UserOfPreference.UserName,
                AutoRefreshPeriod = result.AutoRefreshPeriod
            };
}

The GUI displays the autorefresh value for the user. All the GUI really needs back from the call is one value, AutoRefreshPeriod, and I don't expect it to track anything else returned in the SomeDataTransferObj object.

At a later time, the user can set/hange the autorefresh value and then save it via a second method by populating a new SomeDataTransferObj object as an argument.

Since I have fluently stated this:

.CurrentSessionContext("wcf_operation")

I assume that the session is per method call. That means a call to a set method is starting from scratch again with respect to the UserWorklistPreference record/table???? This is where I'm not sure how to proceed.

I currently have something like the following (not complete code), where the argument userPrefs of type SomeDataTransferObj has its UserId and AutoRefresh properties set by the calling GUI client:

    public int SetUserPreferences(SomeDataTransferObj userPrefs)
    {
        int retVal = 1;

       // method basically does this (ignoring session factory/session/transaction/wcf context logic for now):

        Users user = new Users();   // Entity class.
        user.UserId = userPrefs.UserId;

        UserWorklistPreference workListPrefs = new UserWorklistPreference();    // Entity class.
        workListPrefs.AutoRefreshPeriod = userPrefs.AutoRefreshPeriod;
        workListPrefs.UserOfPreference = user;

        Session.Update(workListPrefs);  // Or try SaveOrUpdate()???

        return retVal;
    }

The problem is that the Session.Update() does nothing while a Session.SaveOrUpdate() call tries to insert a user (which already exists, of course, since we are simply trying to update that existing user's preferences).

How do I achieve the following SQL behavior when I have only the UserId and the autorefresh values?

UPDATE UserWorklistPreference SET AutoRefreshPeriod=userPrefs.AutoRefreshPeriod WHERE UserID=userPrefs.UserId

I could query by user's ID first in SetUserPreferences() to get the UserWorklistPreference record, update that entity using the info in the data transfer object, and then Session.Update(), but wouldn't that be inefficient?

Any advice/help appreciated! Thanks.

-Gav

Foi útil?

Solução

Simply: You don't. The very point of using ORM is to make it so you are working with instances of object, but any changes are automatically persisted to database. Of course there could exist some kind of hack that allows exactly what you want or you can bypass ORM completely and use raw SQL, but then I don't see point of using an ORM framework.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top