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
属性都为空值。以下屏幕截图显示了调试期间的元素实例值:
集合中的第一个元素...获胜!
集合中的第二个元素......巨大的失败!
我已经为上述方法尝试了多种替代实现,即延迟加载、预加载,甚至不从循环内构建列表(我构建了 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);
}
}
最佳答案
- 请检查这是否不是数据相关问题。
否则尝试替换您的代码
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/