【问题标题】:Linq to Entity - error on ICollection<Guid> (code first)Linq to Entity - ICollection<Guid> 上的错误(代码优先)
【发布时间】:2024-05-20 08:00:02
【问题描述】:

所以我们使用代码优先的方法来构建数据库。我遇到了一个问题,解决它的成功率很低。 DB 类(EF - 代码优先)

public partial class Object1
{
    [Key]
    public Guid uid { get; set; }
    public int sequenceNumber { get; set; }
    public bool triggerFlag { get; set; }
    public ICollection<Guid> Object2 { get; set; }
    public ICollection<int> Object3 { get; set; }
}

尝试检索与内部集合相关的特定条件的对象时引发错误

错误代码我尝试了几种不同的 linq 方法来尝试解决错误,但都没有成功(dc 是 EF 中的 dataCONtext)

        return JsonConvert.SerializeObject(dc.Object1.Where
            (x => (!x.Object2.Any() || x.Plants.Contains(object2UID))
             && (x.Object3.Count == 0 || x.Object3.Contains(Object3)).ToList());

产生的错误是

发生“System.NotSupportedException”类型的未处理异常 在 EntityFramework.SqlServer.dll 中

附加信息:指定的类型成员 'Object2' 不是 在 LINQ to Entity 中支持。只有初始化器、实体成员和 支持实体导航属性。

public partial class Object2
{
    [Key]
    public Guid uid { get; set; }
    [Required]
    [StringLength(50)]
    public string model { get; set; }
    [StringLength(3)]
    public string Type { get; set; }
    [StringLength(10)]
    public string alias { get; set; }
}

【问题讨论】:

  • 这可能是因为 Object2 不在您的 Object1 表架构中。如果 Object2 通过外键链接到另一个表,那么您需要对其进行配置并 Include 它以提取其值。此外,在这种情况下,您需要将该属性声明为 virtual
  • @rageit 是的,数据库只显示不是集合的 3 列。但是这种格式在其他地方使用并且有效。有趣的是,如果我只是从 linq 中删除 object2,它会在 object3 上引发相同的错误
  • 请添加 Object2 类?为什么需要 Guid 的导航属性集合?
  • 忘记添加 Object2 可能不是表架构的一部分,因此无法映射
  • @dellywheel 我将在上面更新,使用 Guid 的概念是我们不希望表之间有任何直接链接,如外键(不是我的选择),但它适用于这个项目。

标签: c# linq entity-framework exception linq-to-entities


【解决方案1】:

“无外键”规则消除了关系数据库的一大优势,但在 EF 中您不必使用外键将对象连接在一起。但是,如果您希望使用 EF 的导航属性功能,则确实需要外键。

您应该能够执行以下操作:

public partial class Object1
{
    [Key]
    public Guid uid { get; set; }
    public int sequenceNumber { get; set; }
    public bool triggerFlag { get; set; }
    public Guid Object2Id { get; set; }
    public int Object3Id { get; set; }
}

public partial class Object2
{
    [Key]
    public Guid uid { get; set; }
    [Required]
    [StringLength(50)]
    public string model { get; set; }
    [StringLength(3)]
    public string Type { get; set; }
    [StringLength(10)]
    public string alias { get; set; }
}

public partial class Object3
{
    [Key]
    public int uid { get; set; }
    // Other fields...
}

然后像这样检索它们:

var objects = from o1 in dc.Object1
              join o2 in dc.Object2 on o1.Object2Id equals o2.uid
              join o3 in dc.Object3 on o1.Object3Id equals o3.uid
              select new
              {
                  Object1 = o1,
                  Object2 = o2,
                  Object3 = o3
              };

说了这么多,既然 Object1、Object2 和 Object3 之间存在关系,那么我建议使用关系数据库和实体框架,就像它们被设计使用的方式一样......添加外键。

【讨论】: