【问题标题】:Computed field in Servicestack ormlite errorServicestack ormlite 错误中的计算字段
【发布时间】:2016-07-21 02:59:06
【问题描述】:

我无法让它工作,我使用ServiceStack ormlite Sql servercomputed field添加了data annotation

[Compute, Ignore]
public string FullName { get; set; }

问题是我的LoadSelect<Employee>() 方法没有从computed 字段加载列FullName。为什么?

如果我删除它加载的[Ignore],但是当我使用.create() 方法创建新记录时,它会返回错误,可能是因为它试图为 FullName 字段添加一个值。

表格

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]

员工类:

[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; }
}

获取方法:

    public virtual async Task<IEnumerable<T>> Get<T>() where T : IHasId<int>
    {
        using (var dbCon = DbConnectionFactory.OpenDbConnection())
        {
            return await dbCon.LoadSelectAsync<T>(x => x);
        }
    }

创建方法:

    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);
        }
    }

【问题讨论】:

  • 您能否提供更多有关使用.create() 的详细信息?这是使用Db.Insert&lt;T&gt; 在下面还是其他的自定义包装器?另外,如果您可以为LoadSelect 提供完整的示例 POCO,以便其他人可以重现问题?
  • 是的,这些信息有帮助吗? @Layoric
  • @RogerOliveira 不,它仍然无法运行,它缺少Employee Table 的定义,您是否还可以提供您正在使用的具有 Computed 列的 Employee 的 CREATE TABLE 定义,以便我们对其进行测试本地?
  • @mythz 我删除了一些子表字段并更新了这篇文章中的信息。

标签: c# servicestack ormlite-servicestack


【解决方案1】:

[Ignore] 属性告诉 OrmLite 您希望它完全忽略该属性,这不是您想要的,您只需使用[Compute] 属性来处理我刚刚使用的added a test for in this commit 正在工作的计算列正如在最新版本的 OrmLite 中所预期的那样,例如:

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"));

这也适用于您的 Create() 辅助方法中的异步 API,例如:

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"));

我假设您使用的是旧版本的 OrmLite,如果您升级到最新版本,它应该可以工作。

【讨论】:

  • 新版Service Stack 4.0.60改变了方法参数。我不能使用 dbCon.LoadSelect(x => x) 为什么? .OrderBy(x => x.Field) 也不起作用
  • @RogerOliveira 那些 API 没有改变 unless you're using the deprecated versions,听起来你的构建很脏。确保所有软件包都升级到 v4.0.60 并进行清理/重建,如果这不起作用,请尝试重新启动 VS.NET。
  • 怎么样:LoadSelectAsync 这个不能正常工作:await dbCon.LoadSelectAsync(y => y.IsActive).OrderBy(y => y.AccountName);跨度>
  • 无法将 lambda 表达式转换为类型“ServiceStack.OrmLite.SqlExpression”,因为它不是委托类型
  • @RogerOliveira 查看different Async API Usage examples的此提交
猜你喜欢
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 2012-09-27
  • 2013-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多