代码之家  ›  专栏  ›  技术社区  ›  Collin Barrett

将实体映射到具有部分硬编码的复合外键的查找表

  •  0
  • Collin Barrett  · 技术社区  · 6 年前

    我们有许多不同的表,其中有相关的行 ReferenceDictionary 参考词典 由复合键定义( ReferenceDictionary.Category ReferenceDictionary.Id Category 对于同一相关表中的任何给定行,值总是相同的。

    例如,所有实例 FooEntity 从…起 FooTable 使用值 'FooCategory' 参考字典类别 BarEntity 从…起 BarTable 使用值 'BarCategory' 对于 .

    对于 实际上并没有存储在 可步行的 ,但是(没有数据库列) FooEntity.ReferenceDictionaryCategory BarEntity.ReferenceDictionaryCategory

    我尝试了下面的解决方案使用 [NotMapped] 属性来配置此关系,但我得到一个错误 FooEntity.ReferenceDictionary类别 不是数据库中的列(不是)。

    问题:

    FooEntity.ReferenceDictionary 已成功映射到的实例 使用以下复合键映射?

    • 参考字典类别 = '食品类别'
    • FooEntity.ReferenceDictionaryId

    当前代码:

    public class ReferenceDictionary
    {
        [PrimaryKey(Order = 1)]
        public string Category { get; set; }
    
        [PrimaryKey(Order = 2)]
        public int Id { get; set; }
    
        ...
    }
    
    public class FooEntity
    {
        [Key]        
        public int Id { get; set; }
    
        [NotMapped]
        public string ReferenceDictionaryCategory { get; } = "FooCategory";
    
        public int ReferenceDictionaryId { get; set; }
    
        [ForeignKey(nameof(ReferenceDictionaryCategory) + ", " + nameof(ReferenceDictionaryId))]
        public virtual ReferenceDictionary ReferenceDictionary { get; set; }
    
        ...
    }
    
    public class BarEntity
    {
        [Key]        
        public int Id { get; set; }
    
        [NotMapped]
        public string ReferenceDictionaryCategory { get; } = "BarCategory";
    
        public int ReferenceDictionaryId { get; set; }
    
        [ForeignKey(nameof(ReferenceDictionaryCategory) + ", " + nameof(ReferenceDictionaryId))]
        public virtual ReferenceDictionary ReferenceDictionary { get; set; }
    
        ...
    }
    
    0 回复  |  直到 6 年前
        1
  •  1
  •   cdev    6 年前

    [ForeignKey("ReferenceDictionaryCategory,ReferenceDictionaryId")]
    public virtual ReferenceDictionary ReferenceDictionary { get; set; }
    

    在你尝试加载如下数据之后,

    var test = await _dbcontext.FooEntities.Include(x => x.ReferenceDictionary).ToListAsync();
    

    SELECT  [x].[Id], 
            [x].[ReferenceDictionaryCategory], 
            [x].[ReferenceDictionaryId], 
            [x.ReferenceDictionary].[Category], 
            [x.ReferenceDictionary].[Id]
    FROM [FooEntity] AS [x]
    LEFT JOIN [ReferenceDictionary] AS [x.ReferenceDictionary] 
    ON ([x].[ReferenceDictionaryCategory] = [x.ReferenceDictionary].[Category]) 
        AND ([x].[ReferenceDictionaryId] = [x.ReferenceDictionary].[Id])
    

    这就是为什么你会 [ReferenceDictionaryCategory] 不是列。加上 [NotMapped] 因为这里不是叫专栏的地方。

    有一个解决方法,您可以编写如下查询(如果你不想添加 ReferenceDictionaryCategory 列到 FooEntity

    var result = from fe in _dbcontext.FooEntities
                 join rd in _dbcontext.ReferenceDictionaries
                 on new { Category = "FooCategory", fe.Id } equals new { rd.Category, rd.Id } into data
                 from final in data.DefaultIfEmpty()
                 select new FooEntity
                 {
                     Id = fe.Id,
                     ReferenceDictionaryId = fe.ReferenceDictionaryId,
                     ReferenceDictionary = final
                 };
    

    这将生成这样的sql。

    SELECT [rd].[Category], [rd].[Id], [fe].[Id] AS [Id0], [fe].[ReferenceDictionaryId]
    FROM [FooEntity] AS [fe]
    LEFT JOIN [ReferenceDictionary] AS [rd] ON (N'FooCategory' = [rd].[Category]) AND ([fe].[Id] = [rd].[
    
    推荐文章