c# - EF Code First DbContext 仅为集合的第一个元素返回封装的实体

标签 c# entity-framework linq-to-entities entity-framework-6

EF 的非常奇怪的行为让我抓狂。

问题主要与以下实体类有关,它是封装的属性:

public class ContextParamValue
{
    public Int64 Id { get; set; }

    public Int64 ContextParamId { get; set; }

    public virtual ContextParam ContextParam { get; set; }

    public virtual ContextInstance ContextInstance { get; set; }

    public Int64 ContextInstanceId { get; set; }

    public string Value { get; set; }
}

如您所见,我有一个 ContextParamValue 类,它与 ContextParam 具有单向的一对一关系。因此,ContextParamValue 可以访问 ContextParam,但反之则不行。

让我手足无措的一段代码如下:

public List<ContextParamValue> ParamValuesToList(string[] ParamNames, string[] ParamValues)
{
    if (ParamNames != null && ParamNames.Length != ParamValues.Length)
        throw new System.ArgumentException("ParamNames and ParamValues may not differ in length.");

    List<ContextParamValue> rList = new List<ContextParamValue>();

    for (int i = 0; i < ParamNames.Length; i++)
    {
        string pName = ParamNames[i];
        string pValue = ParamValues[i];

        List<ContextParamValue> lst = db.ContextParamValues
            //.Include(x => x.ContextParam)
            .Where(pv => pv.ContextParam.Name.ToLower().Trim().Equals(pName.ToLower().Trim()))
            .Where(pv => pv.Value.Equals(pValue))
            .ToList<ContextParamValue>();

        rList.AddRange(lst);
    }

    return rList;
}

这段代码的奇怪结果是 ContextParam 只为 rList 中返回的第一个元素加载。 rList 中的所有后续元素的 ContextParam 属性都为空值。以下屏幕截图显示了调试期间的元素实例值:

First element in the list is A-OK 集合中的第一个元素...获胜!

Subsequent elements... HUGE FAIL 集合中的第二个元素......巨大的失败!

我已经为上述方法尝试了多种替代实现,即延迟加载、预加载,甚至不从循环内构建列表(我构建了 ParamNames 的字典ParamValues 数组对象,它允许我在 LINQ 表达式中进行基于集合的匹配)。每次都是一样的结果。

我还包含了我的 DbContext 类中的相关片段:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    ModelMapper.InitializeRelationshipMappings(modelBuilder);
    base.Configuration.LazyLoadingEnabled = true;
}

public static class ModelMapper
{
    public static void InitializeRelationshipMappings(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

        modelBuilder.Entity<Document>()
            .HasRequired(d => d.FileItem)
            .WithOptional(fi => fi.Document)
            .WillCascadeOnDelete(true);


        modelBuilder.Entity<Document>()
            .HasMany(d => d.DocumentClasses)
            .WithMany(dc => dc.Documents);

        modelBuilder.Entity<ContextClass>()
            .HasMany(cc => cc.RequiredClasses);

        modelBuilder.Entity<ContextClass>()
           .HasMany(cc => cc.OptionalClasses);

        modelBuilder.Entity<ContextClass>()
            .HasMany(cc => cc.Params)
            .WithRequired(cp => cp.ContextClass)
            .WillCascadeOnDelete(true);

        modelBuilder.Entity<ContextInstance>()
            .HasRequired(ci => ci.ContextClass);

        modelBuilder.Entity<ContextInstance>()
            .HasMany(ci => ci.ContextParamValues)
            .WithRequired(cpv => cpv.ContextInstance)
            .HasForeignKey(cpv => cpv.ContextInstanceId)
            .WillCascadeOnDelete(true);

        modelBuilder.Entity<ContextParamValue>()
            .HasRequired(cpv => cpv.ContextParam);
    }
}

最佳答案

  1. 请检查这是否不是数据相关问题。
  2. 否则尝试替换您的代码

       List<ContextParamValue> lst = db.ContextParamValues
        //.Include(x => x.ContextParam)
        .Where(pv => pv.ContextParam.Name.ToLower().Trim().Equals(pName.ToLower().Trim()))
        .Where(pv => pv.Value.Equals(pValue))
        .ToList<ContextParamValue>();
    
    rList.AddRange(lst);
    

使用另一个 LINQ

List<ContextParamValue> lst = from db.ContextParamValues.Where(pv => pv.ContextParam.Name.ToLower() == pName.ToLower().Trim()
                          && db.ContextParamValues.Where(pv => pv.Value == pValue)).ToList<ContextParamValue>();
  • 这可能是一个上下文问题,因为它无法加载或无法执行 linq。尝试注释您的代码,我相信您可以使用 SP 来获取此数据(我做了同样的事情并且有效)

关于c# - EF Code First DbContext 仅为集合的第一个元素返回封装的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23414663/

相关文章:

c# - 使用 NPOI 在 Excel 中发布设置整数值

c# - 未选中只是与编译时错误有关吗?

c# - 如何编写可重用的 linq 查询

c# - 在 edmx 中生成的类中带有外键的表缺少成员

c# - 将 LINQ 查询作为字符串发送到 Entity Framework

c# - 将存储过程转换为 LINQ

c# - 在任何浏览器中显示 MSWord 文件内容

c# - ASP.Net MVC 6 身份验证和授权

c# - Entity Framework 查询说找不到我从未指定的列的列

c# - Entity Framework : Mapping a db real to decimal? 无法将 System.Single 转换为 System.Double