查询mongodb中有子对象的时候,结果报错 返回

在子对象的属性上也加了[SugarColumn(IsJson = true)]
但是最后查询时,报错为:
System.InvalidCastException:“Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]' to type 'System.IConvertible'.”
数据为:
实体定义为:
热忱回答(88)
-
fate sta VIP0
1周前报错代码怎么写的 ,是插入还是查询
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:查询啊,自己报错的,截图在上面啊
0 回复 -
fate sta VIP0
1周前这个tojson删掉
不是ORM的方法吧
0 回复 -
fate sta VIP0
1周前直接ToList()看一下是不是OK
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:一样的,不是tojson造成的。
而且,你插入的时候,数据库里面的值也不对
这是什么鬼?:D
0 回复 -
fate sta VIP0
1周前按下面的模版写个可以重现的DEMO
0 回复 -
fate sta VIP0
1周前using SqlSugar; using SqlSugar.MongoDb; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MongoDbTest { public class QueryJsonArray { internal static void Init() { var db = DbHelper.GetNewDb(); db.CodeFirst.InitTables<Student>(); db.DbMaintenance.TruncateTable<Student>(); db.Insertable(new Student() { Age = 1, Name = "tom", SchoolId = "a", Book = new List<Book>() { new Book() { CreateTime = DateTime.Now, Price = 21 } } }).ExecuteCommand(); var data1=db.Queryable<Student>().ToList(); } [SqlSugar.SugarTable("UnitStudentdfsds3zzz1")] public class Student : MongoDbBase { public string Name { get; set; } public string SchoolId { get; set; } public int Age { get; set; } public DateTime CreateDateTime { get; set; } [SqlSugar.SugarColumn(IsJson = true)] public List<Book> Book { get; set; } } public class Book { public decimal Price { get; set; } public DateTime CreateTime { get; set; } } } }
0 回复 -
fate sta VIP0
1周前在我的基础上改一版本能重现的
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:你插入数据的时候估计将子对象转换成数据流了,然后存进去都是byte数组。
我元数据是springboot写进去的,用其他的工具也是正常读取,使用了sqlsugar才不对的。你还是看看子对象在写入的时候是不是有什么问题吧。期待你的修复。
0 回复 -
fate sta VIP0
1周前@兔子罗杰:就是说这个东西不是ORM写入的吗?
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:你应该在IsJson的属性上,将子对象变成json数组,然后字符串的形式拼接上父对象,这样应该就对了,感谢参考我的建议。
0 回复 -
fate sta VIP0
1周前这个需要提供远程字符串,我不清楚你的表里面存的什么样的格式。
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:也是ORM写入的呀,Springboot的ORM写入,用.net的mongodb驱动也能读出来,用其他软件,比如flink for java,都读出正确啊。
0 回复 -
fate sta VIP0
1周前不清楚你说的是什么意思。
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:很简单啊,mongodb里面就是json格式啊,我那个子对象最后就是一个json数组啊
0 回复 -
fate sta VIP0
1周前@fate sta:那你写个可以重现的DEMO给我。
0 回复 -
fate sta VIP0
1周前我这边需要能重现的。因为我重现不了我也不知道怎么改
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:重现什么,跟你上面提供的模版一样的代码啊,但是你插入的时候就是字节流啊
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:就是你再看看,子对象写入的时候是怎么弄的
0 回复 -
fate sta VIP0
1周前db.Ado.ExecuteCommand(@"insertMany UnitSchool123131 [{ ""Name"" : ""XX大学"" }]");
用SQL写个可以重现的
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:这个是写主数据,没有问题的吧
0 回复 -
fate sta VIP0
1周前@兔子罗杰:你写个可以重现的。。我只是个示例。。
0 回复 -
fate sta VIP0
1周前你用Mongodb命令写个可以重现的
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:还有,如果你写子对象有问题,只能把子对象变成json字符串了,或者JsonObject什么的
0 回复 -
fate sta VIP0
1周前@兔子罗杰:需要DEMO。。这样沟通太浪费时间了
0 回复 -
fate sta VIP0
1周前public static string ConnectionString = "mongodb://root:123456@117.72.212.3:27017/testDB?authSource=admin";
这个是公网的mongodb数据库,你可以在这个上面搞一个表 写一个DEMO
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:好,一会我试试
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:我插入了一条我这里的数据,你可以用你们的代码操作一下看看
0 回复 -
fate sta VIP0
1周前@兔子罗杰:实体类发出来
0 回复 -
fate sta VIP0
1周前报错的代码最好提供完整
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:
[SugarTable("a")]
public class VehicleTracksEO : MongoDbBase
{
//外键需要设置ObjectId类型不然存储会的是string
[SugarColumn(ColumnDataType = nameof(ObjectId))]
public string orderId { get; set; } = string.Empty;
[SugarColumn(ColumnDataType = nameof(ObjectId))]
public string carId { get; set; } = string.Empty;
[SugarColumn(IsJson = true)]
public List<Point> latlngPoints { get; set; } = [];
}
public class Point
{
public string? vehicleNo { get; set; } = string.Empty;
public double lat { get; set; }
public double lng { get; set; }
public long timestamp { get; set; }
}
你们直接用你们的代码来操作啊
0 回复 -
fate sta VIP0
1周前一条记录都没有。 是a表吗
0 回复 -
兔子罗杰 VIP0
1周前是a表啊,你看你都读取不出来
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:是a表啊,你看你都读取不出来
0 回复 -
fate sta VIP0
1周前@兔子罗杰:库对吗
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:我在你们a表手动插入了一条数据啊,现在应该是两条
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:就是你给我的库链接啊
0 回复 -
fate sta VIP0
1周前写个空DEMO能重现发我 删掉OBJ和BIN打包上传。这样沟通太浪费时间了
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:你 aggregate a怎么可以嘛?!
0 回复 -
fate sta VIP0
1周前var client = new MongoClient("mongodb://root:123456@117.72.212.3:27017/testDB?authSource=admin"); var database = client.GetDatabase("testDB"); var collections = database.GetCollection<BsonDocument>("a"); var list = collections.AsQueryable<BsonDocument>().ToList();
原生都查不到
0 回复 -
fate sta VIP0
1周前你至少保证用mongodb原生驱动能查到
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:不好意思,数据库错了,是SqlSugarDb,呵呵
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:我刚才验证过了,你们的那个IsJson有问题,对象没转成json字符串
我把属性改正字符串,去掉IsJson标签,写入和读取就对了
0 回复 -
fate sta VIP0
1周前@兔子罗杰:
我拿掉也是NULL
0 回复 -
fate sta VIP0
1周前你最好写个DEMO 吧。这样浪费时间
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:我又在testDB里面的OrderInfo表里面建立了同样的数据,你们不换数据库的话,就用OrderInfo表吧
0 回复 -
fate sta VIP0
1周前提供完整DEMO 。
0 回复 -
fate sta VIP0
1周前并且能重现
0 回复 -
fate sta VIP0
1周前删掉OBJ和BIN打包上传
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:所以说,你的是空的,说明你对字段序列化的时候没弄好,尤其是IsJson的时候,就应该把这个字段变成字符串,然后子类json序列化进去,拼上父类,一次写入mongodb
0 回复 -
fate sta VIP0
1周前提供DEMO。能重现的 。
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:
这样就对了。
但是,你们的IsJson就根本没用了
0 回复 -
fate sta VIP0
1周前浪费很多时间了 ,按你说的无论去掉Isjon都是空的。
0 回复 -
fate sta VIP0
1周前不提供可以重现的DMEO不在回复了。
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:就三个文件
// https://www.donet5.com/home/Doc/3?typeId=2651
using Dm;
using HBDbToolBySqlSugar;
using MongoDB.Bson;
Console.WriteLine("请输入要生成实体类的表名(空格分隔,回车生成)");
var tables = Console.ReadLine();
var instance = DbTool.Instance("mongodb://", SqlSugar.DbType.MongoDb);
//instance.GenerateEntities(["VehicleTracks"]);
//instance.GetDb().Queryable<VehicleTracksEO>().ToList().ForEach(x =>
//{
// Console.WriteLine($"OrderId: {x.OrderId}, CarId: {x.CarId}, Points Count: {x.LatlngPoints}");
//});
var result = instance.GetDb().Queryable<VehicleTracksEO>().Where(it => it.Id == "6864dc62d35094e98ec9dc73").ToList().ToJson();
Console.WriteLine(result);
Console.ReadLine();
//var data = new List<Point>
//{
// new() {
// vehicleNo = "车牌号1",
// lat = 39.9042,
// lng = 116.4074,
// timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
// },
// new() {
// vehicleNo = "车牌号2",
// lat = 34.0522,
// lng = 118.2437,
// timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
// }
//};
//instance.GetDb().Insertable(new VehicleTracksEO
//{
// orderId = ObjectId.GenerateNewId().ToString(),
// carId = ObjectId.GenerateNewId().ToString(),
// latlngPoints = data.ToJson()
//}).ExecuteCommand();
========================================================================
using MongoDB.Bson;
using SqlSugar;
using SqlSugar.MongoDb;
namespace HBDbToolBySqlSugar
{
[SugarTable("VehicleTracks")]
public class VehicleTracksEO : MongoDbBase
{
//外键需要设置ObjectId类型不然存储会的是string
[SugarColumn(ColumnDataType = nameof(ObjectId))]
public string orderId { get; set; } = string.Empty;
[SugarColumn(ColumnDataType = nameof(ObjectId))]
public string carId { get; set; } = string.Empty;
//[SugarColumn(IsJson = true)]
public string latlngPoints { get; set; } = string.Empty;
}
public class Point
{
public string? vehicleNo { get; set; } = string.Empty;
public double lat { get; set; }
public double lng { get; set; }
public long timestamp { get; set; }
}
}
============================================================
using SqlSugar;
using System.Data;
using System.Reflection;
namespace HBDbToolBySqlSugar
{
public class DbTool
{
private readonly SqlSugarClient _db;
private static readonly DbTool? _instance;
public static DbTool Instance(string connectionString, SqlSugar.DbType dbType) => _instance ?? new DbTool(connectionString, dbType);
private DbTool(string connectionString, SqlSugar.DbType dbType)
{
_db = new SqlSugarClient(new ConnectionConfig
{
ConnectionString = connectionString,
DbType = dbType,
IsAutoCloseConnection = true
},
it =>
{
it.Aop.OnLogExecuting = (sql, para) =>
{
Console.WriteLine(UtilMethods.GetNativeSql(sql, para));
};
});
}
public SqlSugarClient GetDb()
{
return _db;
}
}
}
0 回复 -
fate sta VIP0
1周前提供完整可以跑的。
0 回复 -
fate sta VIP0
1周前删掉OBJ和BIN打包上传
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:那你们还是再看看子集记录是在mongodb里面怎么保存的吧,可能你们在开发的时候还没考虑到这种情况。
我也是随便测试一下,毕竟直接用.net的BSON直接可以操作数据。等你们后续发现问题再测试升级吧 :)
0 回复 -
fate sta VIP0
1周前我这边已经重现了,你用的A表名是我已存在的表名
导致2条记录一条是我以前插入的结构
一条是新插入的结构
因为结构不一样导致读取失败。
0 回复 -
fate sta VIP0
1周前SqlSugar.MongoDbCore 5.1.4.203
更新这个版本查询的修复了 ,保证每条记录的结构一致。
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:monogodb里面的数据字段不可能每条保持一致。
上一条记录的结构和下一条记录的结构可以不一致的,mongodb是取合集,比如,第一条记录是 name, addr, 第二条记录只有mobile,那么它作为一条记录显示就变成三个字段了,即:name,addr,mobile
0 回复 -
fate sta VIP0
1周前@兔子罗杰: ORM要读取有哪些列。以第一条为基准。
0 回复 -
fate sta VIP0
1周前保证第一条是标准的。
0 回复 -
fate sta VIP0
1周前保证第一条是标准的。
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:
我用mongodb.drive自带的insert和查询,对带有子集的记录插入和查询都是没有问题的,而且都是可以读取和写入我提供的数据结构的。
而我发觉用sqlsugar插入和查询还是有问题,用你说的最新版本。
大多是出现在MongoDbInsertBuilder里面 :)
0 回复 -
fate sta VIP0
1周前@兔子罗杰:你不提供DEMO我这边进度会很慢。因为我只慢慢摸索。你说的出错是哪儿出错我也不清楚
0 回复 -
fate sta VIP0
1周前我这边测试用例是OK的。空表写入
0 回复 -
fate sta VIP0
1周前-
0 回复 -
fate sta VIP0
1周前using MongoDB.Bson; using SqlSugar.MongoDb; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MongoDbTest { internal class Unitdfasfysfs { public static void Init() { var db = DbHelper.GetNewDb(); db.Insertable(new VehicleTracksEO() { carId= ObjectId.GenerateNewId() + "", orderId =ObjectId.GenerateNewId()+"", latlngPoints=new List<Point>() { new Point(){ lat=1, lng=1, timestamp=11, vehicleNo="aa" } } }).ExecuteCommand(); var list=db.Queryable<VehicleTracksEO>().ToList(); } } [SugarTable("unitadsfasfdsys")] public class VehicleTracksEO : MongoDbBase { //外键需要设置ObjectId类型不然存储会的是string [SugarColumn(ColumnDataType = nameof(ObjectId))] public string orderId { get; set; } = string.Empty; [SugarColumn(ColumnDataType = nameof(ObjectId))] public string carId { get; set; } = string.Empty; [SugarColumn(IsJson = true)] public List<Point> latlngPoints { get; set; } =new List<Point>() { }; } public class Point { public string? vehicleNo { get; set; } = string.Empty; public double lat { get; set; } public double lng { get; set; } public long timestamp { get; set; } } }
完整测试用例 跟本重现不了你说的。
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:我的demo都在上面贴了啊
然后我找了有问题的地方,MongoDbInsertBuilder:
你们有空再查一下吧 :)
0 回复 -
fate sta VIP0
1周前@兔子罗杰:你的源码不是最新的
0 回复 -
fate sta VIP0
1周前查询的我已经改过了,多加了一个if
0 回复 -
fate sta VIP0
1周前插入目前没有发现任何问题
0 回复 -
fate sta VIP0
1周前SqlSugar.MongoDbCore 5.1.4.204
这次应该都好了 更新到204
0 回复 -
fate sta VIP0
1周前0 回复 -
兔子罗杰 VIP0
1周前@fate sta:
整体测试下来,基本只能用个基础功能,还是不能用嵌套数据(数据操作的结果根本不对),跟mongodb.driver提供的自身的orm不好比,可能你们的实现思路是有问题的。
建议这个SqlSugar.MongodbCore可以取消了,Mongodb.Drver本身就可以ORM。当然,你们要让mongodb通过sqlsugar和其他数据库中的数据join,可以重新设计一下SqlSugar.MongodbCore的功能。
题外话,Mongodb是放json数据的,每条json数据的结构是可以不同的,mongodb显示是所有记录字段的合并集。
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:
这是我用Mongodb.Driver自己提供的ORM来读取数据的,两条记录你可以用两个不同的实体来读取,实际存储数据在你们的数据库SqlSugarDb.a表中,如下
0 回复 -
fate sta VIP0
1周前第一条是错误记录删掉。
0 回复 -
fate sta VIP0
1周前实体结构是固定的。用ORM的话你不能用mongodb的思维设计表结构。
0 回复 -
fate sta VIP0
1周前针对这种不同结构我在想一下如何去处理
[ {id:`1} {name:"a"} ]
比如返回这种合并后的结构。
[{id:1,name:null},{id:0,name;"a"}]
0 回复 -
fate sta VIP0
1周前原生的功能也支持
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:实体结构是固定的,但是你可以将不同实体往一个表里面写哦,你读取的时候可以根据指定不同的实体类来取数据哦。
mongodb是用来存文档的,不同文档的格式是可以在同一个表里面的,这个也是mongodb最大的好处啊。
internal class BaseService<TEntity> where TEntity : class, new()
{
protected readonly IMongoCollection<TEntity> _collection;
public BaseService()
{
var client = new MongoClient("mongodb://root:123456@117.72.212.3:27017/SqlSugarDb?authSource=admin");
var database = client.GetDatabase("SqlSugarDb");
_collection = database.GetCollection<TEntity>("a");
}
public async Task<List<TEntity>> GetAllAsync() =>
await _collection.Find(_ => true).ToListAsync();
}
你看,我用原生的,比你们的这个SqlSugar.MongodbCore方便多了,最多自己再写个分页,ok
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:mongodb,最大的好处是能够检索json里的不同数据,因为最后都变成动态的字段。
如果换了其他的数据库,你的json只能当一个字符串字段来存取。
SqlSugar.MongoDBCore这个项目最多封装一下原生的ORM得了,他反正也不是做复杂sql查询的。
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:上面贴图里面的两条数据不是错误数据,正是我原生ORM写入的数据和你写入的数据一同展示的。我就是跟你说明,不同结构的数据是可以在一个表里面的。
0 回复 -
fate sta VIP0
1周前这个已经在处理了。支持不同结构的读取
0 回复 -
fate sta VIP0
1周前SqlSugar.MongoDbCore 5.1.4.205
过五分钟升级到 205
0 回复 -
fate sta VIP0
1周前新版本测试, 我这边是可以了
SqlSugar.MongoDbCore 5.1.4.205
0 回复 -
兔子罗杰 VIP0
1周前@fate sta:测了一下,凑合可以读取。
为什么说是凑合呢,因为,你们还是在数据转换上会报错。应该是那个外键的objectid,一定是字符串的问题吧。但是我在其他系统里面设置的是long类型哦,到了你这里转换就还是会报错。
如果想做到完美匹配其他语言写入的mongodb数据,你们这个版本还得动脑筋升级啊 :D
0 回复