I couldn't make it work, I added the data annotation for a computed field using ServiceStack ormlite Sql server:
[Compute, Ignore]
public string FullName { get; set; }
The problem is that my LoadSelect<Employee>() method doesn't load the colunm FullName from a computed field. Why?
if I remove the [Ignore] it loads, but then when I use the.create() method to create a new record, it returns an error, probably because it tries to add a value for the FullName field.
Table
CREATE TABLE [dbo].[Employee](
[EmployeeId] [int] IDENTITY(1,1) NOT NULL,
[FullName] AS (concat(ltrim(rtrim([FirstName])),' ',ltrim(rtrim([LastName])))) PERSISTED NOT NULL,
[FirstName] [nvarchar](55) NOT NULL,
[LastName] [nvarchar](55) NULL,
[Username] [nvarchar](55) NOT NULL,
[Password] [nvarchar](55) NULL
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[EmployeeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
Employee class:
[Schema("dbo")]
[Alias("Employee")]
public class Employee : IHasId<int>
{
[PrimaryKey]
[Alias("EmployeeId")]
[AutoIncrement]
[Index(Unique = true)]
public int Id { get; set;}
[Required]
public string FirstName { get; set; }
public string LastName { get; set; }
[Required]
[Index(true)]
public string Username { get; set; }
public string Password { get; set; }
[Compute, Ignore]
public string FullName { get; set; }
}
Get method:
public virtual async Task<IEnumerable<T>> Get<T>() where T : IHasId<int>
{
using (var dbCon = DbConnectionFactory.OpenDbConnection())
{
return await dbCon.LoadSelectAsync<T>(x => x);
}
}
Create method:
public virtual async Task<T> Create<T>(T obj) where T: IHasId<int>
{
using (var dbCon = DbConnectionFactory.OpenDbConnection())
{
// if there is an id then INSERTS otherwise UPDATES
var id = obj.GetId().SafeToLong();
if (id > 0)
dbCon.Update(obj);
else
id = dbCon.Insert(obj, true);
// returns the object inserted or updated
return await dbCon.LoadSingleByIdAsync<T>(id);
}
}
The [Ignore] attribute tells OrmLite you want it to ignore the property completely which is not what you want, you need to just use the [Compute] attribute to handle computed columns which I've just added a test for in this commit which is working as expected in the latest version of OrmLite, e.g:
db.DropTable<Employee>();
db.ExecuteSql(@"
CREATE TABLE [dbo].[Employee](
[EmployeeId] [int] IDENTITY(1,1) NOT NULL,
[FullName] AS (concat(ltrim(rtrim([FirstName])),' ',ltrim(rtrim([LastName])))) PERSISTED NOT NULL,
[FirstName] [nvarchar](55) NOT NULL,
[LastName] [nvarchar](55) NULL,
[Username] [nvarchar](55) NOT NULL,
[Password] [nvarchar](55) NULL
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED ([EmployeeId] ASC)");
var item = new Employee
{
FirstName = "FirstName",
LastName = "LastName",
Username = "Username",
Password = "Password",
FullName = "Should be ignored",
};
var id = db.Insert(item, selectIdentity: true);
var row = db.LoadSingleById<ComputeTest>(id);
Assert.That(row.FirstName, Is.EqualTo("FirstName"));
Assert.That(row.FullName, Is.EqualTo("FirstName LastName"));
row.LastName = "Updated LastName";
db.Update(row);
row = db.LoadSingleById<ComputeTest>(id);
Assert.That(row.FirstName, Is.EqualTo("FirstName"));
Assert.That(row.FullName, Is.EqualTo("FirstName Updated LastName"));
Which also works using the async API's in your Create() helper method, e.g:
var row = await Create(item);
Assert.That(row.FirstName, Is.EqualTo("FirstName"));
Assert.That(row.FullName, Is.EqualTo("FirstName LastName"));
row.LastName = "Updated LastName";
row = await Create(row);
Assert.That(row.FirstName, Is.EqualTo("FirstName"));
Assert.That(row.FullName, Is.EqualTo("FirstName Updated LastName"));
I'm assuming you're using an older version of OrmLite, if you upgrade to the latest version it should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With