Skip to content

使用动态类型Insert从基类AsType 为子类后会向主键列插入数据 问题 #1496

Open
@hyzx86

Description

@hyzx86

最新版 freesql + SQLServer 2016

核心代码如下:

allModelList 是 从json 转换过来然后动态生成的类型
传入数据类型转换没有问题,
过程中为了方便进行条件更新和条件删除,将对象集合转换为基类进行处理了(类型装箱应该不会影响数据内容)
然后在插入时 如果使用 DIndexBase 作为初始类型 会导致主键列在生成SQL时被赋值

                        var insertQuery = _fsql.Insert<DIndexBase>().AsType(type).AppendData(updateList);

如果使用object 则不存在这种问题
var insertQuery = _fsql.Insert().AsType(type).AppendData(updateList);

                var config = _dynamicIndexAppService.GetDynamicIndexConfig(typeName, true);
                if (config != null)
                {
                    var type = _dynamicIndexAppService.GetDynamicIndexType(config);
                    var table = _fsql.CodeFirst.GetTableByEntity(type);
                    var typeFilterdList = contentItems.Where(x => x.ContentItem.ContentType == typeName)
                        .Select(x => x.ContentItem);
                    _logger.LogWarning(
                        "数据导入,更新动态索引DIndex ContentType: {typeName} 动态索引 ,Table:{tableName}, 共:{count}条, 分页大小:{pageSize}",
                        config.TypeName, config.TableName, typeFilterdList.Count(), DefaultPageSize);
                    var allModelList = typeFilterdList.ToModel(config, type, table);
//此处转换为 基类方便操作数据
                    var updateList = allModelList.Take(DefaultPageSize).OfType<DIndexBase>();
                    var pageIndex = 0;
                    totalUpdated[typeName] = 0;
                    try
                    {
                        while (updateList.Any())
                        {
                            var ids = updateList.Select(x => x.DocumentId).Distinct();
                            if (config.IndexLastVersion)
                            {
                                //更新现有文档
                                var deletePreviewVersions = _fsql.Delete<DIndexBase>().AsType(type)
                                     .Where(x => ids.Contains(x.DocumentId));

                                if (_session.CurrentTransaction != null)
                                {
                                    deletePreviewVersions.WithTransaction(_session.CurrentTransaction);
                                }
                                await deletePreviewVersions.ExecuteAffrowsAsync();
                            }
                            else
                            {
                                //更新现有文档
                                var updateCmd = _fsql.Update<DIndexBase>().AsType(type)
                                     .Set(x => new { Latest = false, Published = false })
                                     .Where(x => ids.Contains(x.DocumentId));

                                if (_session.CurrentTransaction != null)
                                {
                                    updateCmd.WithTransaction(_session.CurrentTransaction);
                                }
                                await updateCmd.ExecuteAffrowsAsync();
                            }


                            var insertQuery = _fsql.Insert<object>().AsType(type).AppendData(updateList);
                            if (_session.CurrentTransaction != null)
                            {
                                insertQuery.WithTransaction(_session.CurrentTransaction);
                            }
                            switch (_fsql.Ado.DataType)
                            {
                                case FreeSql.DataType.SqlServer:
                                    _logger.LogWarning("检测到 SqlServer 数据库,已开启SqlBulkCopy");
                                    await insertQuery.ExecuteSqlBulkCopyAsync();
                                    totalUpdated[typeName] += updateList.Count();
                                    break;
                                case FreeSql.DataType.MySql:
                                    _logger.LogWarning("检测到 MySql 数据库,已开启 ExecuteMySqlBulkCopy ");
                                    await insertQuery.ExecuteMySqlBulkCopyAsync();
                                    totalUpdated[typeName] += updateList.Count();
                                    break;
                                case FreeSql.DataType.PostgreSQL:
                                    _logger.LogWarning("检测到 PostgreSQL 数据库,已开启 ExecutePgCopy ");
                                    await insertQuery.ExecutePgCopyAsync();
                                    totalUpdated[typeName] += updateList.Count();
                                    break;
                                default:
                                    totalUpdated[typeName] += await insertQuery.ExecuteAffrowsAsync();
                                    break;
                            }

DIndexBase 类型

public abstract class EocDocumentIndex : MapIndex, IFreeSqlMapDocumentIndex
    {
        [Column(IsPrimary = true, IsIdentity = true, IsNullable = false)]
        new public virtual long Id { get => base.Id; set { base.Id = value; } }

        public virtual long DocumentId { get; set; }

    }

//这里实际就是Table
    [EOCTable(Name = "ContentItemIndex")]
    public class DIndexBase : EocDocumentIndex //
    {
        [Column(IsPrimary = true, IsIdentity = true, CanInsert = false, CanUpdate = false)]
        public override long Id { get => base.Id; set { base.Id = value; } }

        [Column(StringLength = 26)]
        public string ContentItemId { get; set; }
        [Column(StringLength = 26)]
        public string ContentItemVersionId { get; set; }
        public bool Published { get; set; }
        public bool Latest { get; set; }
        [Column(StringLength = 255)]
        public string DisplayText { get; set; }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions