Pergunta

I have following scenario...

  • Massive Micro-ORM
  • .NET framework 4.0
  • SQL Server 2008R2

Model:

public class sUser : DynamicModel
{
    public sUser() : base(Model.strConnection, "Users", "UserId") { }
}

public class Test
    {
        public void UpdateUser(string user)
        {
            dynamic User = GetUser(user);

            //Dynamically generated User object has many columns
            // I Update following fields...
            User.Address1 = "123 Main Street";
            User.Address2 = "Suite# 456";
            User.CityName = "Princeton";
            User.State = "NJ";
            User.Zipcode = "08540";
            //And update some more fields in Users object

           //I could do this...
            //var upd = new { Address1 = "123 Main Street", Address2 = "Suite# 456", ...};
            //User.Update(upd, User.UserID);

            //But would like to pass entire object, so I do not have to form all updated name/value in the update statement
            User.Update(User, User.UserID);

            //But Users table has a column with IDENTITY SEED,
            //And if I pass entire object for update it errors out
            //Cannot update identity column 'RefNo'
        }

        public dynamic GetUser(string userName)
        { 
            dynamic table = new sUser();
            var objUser = table.First(UserName: userName);

            return objUser;
        }
    }

Users table has a column RefNo with IDENTITY SEED=1, and when I update entire User object, it errors out Cannot update identity column 'RefNo'. I would like to pass entire object for update rather than forming long update statement.

How can I handle this?

Thanks.

Foi útil?

Solução 2

Modify Massive.cs - Add following under DynamicModel class

private string IdentityColumn { get; set; }

 private string GetIdentityColumn()
 {
    return (string)Scalar("SELECT C.name AS IdentityColumn FROM sys.columns C Inner Join sys.tables T ON T.object_id = C.object_id WHERE C.is_identity = 1 And T.name = '" + TableName + "'");
 }

And under CreateUpdateCommand method add following...

IdentityColumn = GetIdentityColumn();

And under foreach loop modify if statement to following...

if (!item.Key.Equals(PrimaryKeyField, StringComparison.OrdinalIgnoreCase) && item.Value != null && item.Key != IdentityColumn)

Above change into Massive library would allow us to update model with identity column. Limitation: Works for Table with one IDENTITY column.

Outras dicas

If your Users table has a column RefNo with IDENTITY SEED = 1, then that would imply it is your primary key. In you sUser class, you are calling the base constructor with:

base(Model.strConnection, "Users", "UserId")

This call is telling Massive that the primary key column is UserId - what happens if you instead pass it RefNo?

Edit:

I think I see the problem you are having: Massive will generate an update statement including all the properties of your object, including RefNo. Because the database is taking care of this column (via IDENTITY SEED), you can't modify or set this value.

What I would suggest instead is taking advantage of the fact that User is returned as an ExpandoObject. What you could do is this:

((IDictionary<string, object>)User).Remove("RefNo");
User.Update(User, User.UserID);

What this will do is remove the RefNo property from the object, meaning that it won't be included in the update statement that gets created, which should in turn result in the Update call succedding.

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