【问题标题】:OrmLite Inserting 0 and instead of auto-incrementing primary keyOrmLite 插入 0 而不是自动递增主键
【发布时间】:2014-05-07 16:14:33
【问题描述】:

我正在尝试为我们的对象创建一个通用的Insert<T>。我是 OrmLite 的新手,所以我仍在阅读它。使用的对象不使用Id 属性,它们具有更详细的名称。

例如,这是一个基本的 POCO:

public class Customer
{
    public int CustomerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    ...etc.
} 

所以主键是CustomerId,通过更多阅读我发现OrmLite喜欢使用属性Id作为主键。由于我们有一个约定,不能只使用名​​称 Id 来表示 FK,因此我无法切换。然而,进一步阅读似乎我可以用一个或两个属性装饰该属性并让它工作。

这是我正在使用的:

public class Customer
{
    [AutoIncrement]
    [Alias("CustomerId")]
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    ...
}

我收到SqlException 说明以下内容:

附加信息:无法将值 NULL 插入“CustomerId”列, 表'XXX.dbo.Customer';列不允许空值。插入失败

我做了更多阅读,并认为我可以通过从接口继承来解决这个问题。

public class Customer : IHasId<int>
{
    [AutoIncrement]
    [Alias("CustomerId")]
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    ...
}

我已经尝试过使用PrimaryKey 属性,但仍然得到相同的结果。

有人遇到过这样的问题吗?如果你做了你是怎么解决的?我很难找到有关此事的更多信息。

我可以去掉属性并将属性重新命名为 CustomerId,以便它与 db 表匹配,并将插入到表中,但它总是将 0 作为键,这很有意义,因为它是默认值int 的值,但当它必须是自动递增的主键时对我没有帮助。作为旁注,我正在使用ServiceStack.OrmLite.SqlServer.3.9.71 和 SQL Server 2008

更新 1

所以我今天再次浏览了 3.9 版 ServiceStack.OrmLite 的文档,并阅读了他们对当我没有主键具有“Id”属性的 POCO 时应该做什么的描述。如下:

... 按照惯例,OrmLite 期望它是 Id,尽管您可以使用 [Alais("DbFieldName")] 属性将其映射到具有不同名称的列或使用 [PrimaryKey] 属性告诉 OrmLite 使用主键的不同属性。

我使用了这两个示例,实际上它确实将我的数据插入到 SQLDatabase。但是,它仍然为 CustomerId 主键插入 0。

如果我使用 AutoIncrement 属性,它会抛出 SqlException:

System.Data.dll 中出现“System.Data.SqlClient.SqlException”类型的异常,但未由用户代码处理。附加信息:无法将值 NULL 插入列“CustomerId”、表“dbo.Customer”;列不允许空值。插入失败。

有人遇到过这个问题吗?我总是遇到障碍。

【问题讨论】:

  • 只是为了它——你试过如果使用Id 会起作用吗?您可以始终使用 Customer.Id 作为客户表中的 PK,并且仍然在子表中使用 CustomerId 来引用它(因此不会违反您的约定 - 对吧?)
  • 对不起,在这种情况下,它只有在我还将属性名称更改回 CustomerId 以使其与 db 表匹配时才有效。编辑帖子以保持清晰。

标签: c# sql sql-server-2008 ormlite ormlite-servicestack


【解决方案1】:

我尝试了同样的问题。您的以下代码已经很好了。

公共类客户 { [自动递增] [别名(“客户 ID”)] 公共 int ID { 获取;放; } 公共字符串名字 { 获取;放; } 公共字符串姓氏{得到;放; } ... }

问题不是来自 ORMLITE,而是来自您的数据库。实际上,我认为您的表的主键列“CustomerId”将他的属性“Identity”设置为“False”。您必须将其设置为“True”或“Yes”,并将“Identity Increment”和“Identity Seed”设置为 1。

【讨论】:

    【解决方案2】:

    在 v4.0.40 中,servicestack 通过命名约定(“column_name”== OrmLiteConfig.IdField)检索主键列,如 OrmLiteConfigExtensions.cs 中的以下代码所示:

        internal static bool CheckForIdField(IEnumerable<PropertyInfo> objProperties)
        {
            // Not using Linq.Where() and manually iterating through objProperties just to avoid dependencies on System.Xml??
            foreach (var objProperty in objProperties)
            {
                if (objProperty.Name != OrmLiteConfig.IdField) continue;
                return true;
            }
            return false;
        }
    

    因此,将[AutoIncrement][Alias] 一起使用应该不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-07
      • 1970-01-01
      相关资源
      最近更新 更多