【问题标题】:Create Database table from model with enum using Umbraco.Core.Persistence使用 Umbraco.Core.Persistence 从带有枚举的模型创建数据库表
【发布时间】:2015-02-20 16:00:04
【问题描述】:

如果此表不存在,则希望在应用程序启动时创建此表。

代码:

public class Database : ApplicationEventHandler
{
    protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        var db = applicationContext.DatabaseContext.Database;

        //Cant add this table due to the ENUM
        if (!db.TableExist("FormData"))
        {
            db.CreateTable<FormData>(false);
        }
    }
}

型号:

[PrimaryKey("Id")]
public class FormData
{
    [PrimaryKeyColumn(AutoIncrement = true, IdentitySeed = 1)]
    public int Id { get; set; }

    [NullSetting(NullSetting = NullSettings.NotNull)]
    public FormType Type { get; set; }

    [NullSetting(NullSetting = NullSettings.NotNull)]
    public string Data { get; set; }

    [NullSetting(NullSetting = NullSettings.NotNull)]
    public DateTime Date { get; set; }
}

错误信息:

[InvalidOperationException:序列不包含匹配元素] System.Linq.Enumerable.First(IEnumerable1 source, Func2 谓词)+415 Umbraco.Core.Persistence.SqlSyntax.SqlSyntaxProviderBase1.FormatType(ColumnDefinition column) +1225 Umbraco.Core.Persistence.SqlSyntax.SqlSyntaxProviderBase1.Format(ColumnDefinition 列) +155 Umbraco.Core.Persistence.SqlSyntax.SqlSyntaxProviderBase1.Format(IEnumerable1 列)+144 Umbraco.Core.Persistence.SqlSyntax.SqlSyntaxProviderBase`1.Format(TableDefinition 表) +131 Umbraco.Core.Persistence.PetaPocoExtensions.CreateTable(数据库数据库,布尔覆盖,类型模型类型)+161 Umbraco.Core.Persistence.PetaPocoExtensions.CreateTable(Database db, Boolean overwrite) +121

查看错误我认为不更新核心没有解决方案,但希望你们能提供帮助

【问题讨论】:

    标签: c# umbraco umbraco7


    【解决方案1】:

    根据@Ryios 给出的答案,我认为这样的事情很好:

    /// <summary>
    /// Don't use this to get or set.
    /// This must however be kept as public or db.CreateTable()
    /// will not insert this field into the database.
    /// </summary>
    [NullSetting(NullSetting = NullSettings.NotNull)]
    [Column("type")]
    public int _type { get; set; }
    
    /// <summary>
    /// This field is ignored by db.CreateTable().
    /// </summary>
    [Ignore]
    public FormType Type
    {
        get
        {
            return (FormType)_type;
        }
        set
        {
            _type = (int)value;
        }
    }
    

    在代码中,应该使用Type 而不是_type,这样才能使枚举受益。 _type 仅作为插入数据库表的字段存在。

    【讨论】:

    • 是的,这有点干净,我喜欢。但是 PetaPoco v4.0+ 支持私有/受保护成员,因此如果您使用较新版本,则无需公开 _Type。
    【解决方案2】:

    无需修改 PetaPoco 或使用不同的分叉,您可以使用这样的解决方案,

    [Column(type), NullSetting(NullSetting = NullSettings.NotNull)]
    public int TypeAsInt { get; set; }
    
    [Ignore]
    public FormType TypeAsEnum { get { return (FormType)TypeAsInt; } }
    

    Peta poco 将忽略带有 Ignore 标记的属性,这意味着它不会在创建表格或选择结果时尝试使用它们。相反,TypeAsInt 将在表中创建为 int 类型。

    然后在您的代码中,您可以随时使用 TypeAsEnum,只要您想要从 TypeAsInt 转换的 FormType 版本。

    【讨论】:

      【解决方案3】:

      我相信这个问题是因为你的类有一个非 sql 类型,所以它不知道如何处理它。特别是,您有一个名为“FormType”的属性,其类型为“FormType”。 PetaPoco 不知道 SQL 列类型是什么。如果你想自动创建表,你需要确保你的类只使用可以映射到 SQL 列类型的属性类型。

      您可能还会遇到一些问题,例如,如果您希望列为 nvarchar(max),则无法告诉持久层执行 max,因此您必须将其设置为 nvarchar(x),其中x 是一个数字,然后在创建表后运行 alter 语句将类型更改为 nvarchar(max)。

      【讨论】:

      • 如果字段是 Enum,您需要将其存储为基本类型(可能是 int?)而不是 Enum。我认为 PetaPoco 有一些分支可以做 Enums,但正如你所说,你必须更新核心才能使其工作。
      • 如果我手动创建表,代码运行并将数据保存为整数,petapoco 会按照您的希望执行所有映射。只是不能从代码创建表。看起来如果我想这样做的话,我可能不得不添加另一个 int 属性来存储列。
      • 是的,没错。 Peta Poco 会映射它,它只是无法创建它,因为它不知道如何处理 Enum。遗憾的是,PetaPoco 的表格创建功能非常简单!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 2021-03-17
      • 1970-01-01
      • 2010-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多