Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架-GetHashCode中的子对象为null_C#_Asp.net Mvc_Entity Framework - Fatal编程技术网

C# 实体框架-GetHashCode中的子对象为null

C# 实体框架-GetHashCode中的子对象为null,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,实体框架6 MVC5 我是EF和MVC的新手,我有一个场景,我有一个覆盖Equals和GetHashCode的类: EF代码: public partial class ProdCategory { public long ProdID { get; set; } public int CategoryID { get; set; } public bool PermanentlyDelete { get; set; } public System.DateTim

实体框架6 MVC5

我是EF和MVC的新手,我有一个场景,我有一个覆盖Equals和GetHashCode的类:

EF代码:

public partial class ProdCategory
{
    public long ProdID { get; set; }
    public int CategoryID { get; set; }
    public bool PermanentlyDelete { get; set; }
    public System.DateTime DateCreated { get; set; }

    public virtual Category Category { get; set; }
    public virtual Product Product { get; set; }
}
我的代码:

    public override bool Equals(object obj)
    {
        if (obj == null | (!object.ReferenceEquals(this.GetType(), obj.GetType())))
        {
            return false;
        }

        ProdCategory p = (ProdCategory)obj;

        if (this.Category == p.Category && this.Product == p.Product)
        {
            return true;
        }

        return false;
    }
    public override int GetHashCode()
    {
        unchecked
        {                
            var result = 0;
            result = (result * 397).GetHashCode() ^ this.Product.GetHashCode();
            result = (result * 397).GetHashCode() ^ this.Category.GetHashCode();
            return result;
        }
    }
该类成为产品的子对象,当我转到产品列表查看GetHashCode错误时

Heisenberg.dll中发生“System.NullReferenceException”类型的异常,但未在用户代码中处理

我认为这可能是一个延迟加载问题,但是产品对象存在于GetHashCode函数中,所以我假设如果存在,那么类别应该是。。?我试图使用以下命令强制加载prodCategory:

var products = db.Products.Include(p => p.ProdCategories);
但这没什么区别。因此,我认为我需要在ProdCategory中强制加载该类别,但我无法计算出该类别的语法

作为测试,我注释掉了GetHashCode函数-页面加载正常,我可以转到产品的详细信息视图并查看prodCategory详细信息,因此它确实会在某个时候填充。这就是我被抛下的原因!不知道还可以尝试什么

我希望有人能看出我错在哪里

更新: 如果我在GetHashCode中设置了一个断点——当它第一次命中它时,Product被填充,Category为null。如果我不运行分类行并继续,断点将再次命中。这一次将同时填充产品和类别


有人能解释一下发生了什么,bst的行动方针是什么吗?我可以在GetHashCode中检查是否为null,但它确实不应该为null,我只是隐藏了错误。

无论如何,您应该根据外键执行
GetHashCode

public override int GetHashCode()
{
    unchecked
    {                
        var result = this.ProdID.GetHashCode();
        result = (result * 397) ^ this.CategoryID;
        return result;
    }
}
永远不会设置外部id(假设该项是从数据库“获取”的),这是因为外部id位于行本身(因此不需要联接)。为了解决第一次实例化对象时哈希代码出错的问题,我将这样做

public partial class ProdCategory
{
    protected ProdCategory() {} //protected default constructor is required by EF

    public ProdCategory(Category category, Product product)
    {
        this.Category = category;
        this.Product = product;
        this.ProdID = product.Id;
        this.CategoryID = category.Id;
    }

    public long ProdID { get; protected set; }
    public int CategoryID { get; protected set; }
    public bool PermanentlyDelete { get; set; }
    public System.DateTime DateCreated { get; set; }

    public virtual Category Category { get; protected set; }
    public virtual Product Product { get; protected set; }
}

ProdCategory
做什么?它看起来只是一个关联,在这种情况下,它不应该存在于域模型中。它包含其他属性,如MarkForDelete。第一个问题是:为什么需要Hashcode?您只能将其用于内存中的对象,而不能用于针对数据库的LINQ查询,而我认为它是在LINQ查询中进行排序和比较的。在该项目中创建重写的equals时,我被告知应该始终更改GetHasCode函数以进行匹配,因为“Equal”对象应该始终具有相同的hashcode?是否有任何代码需要显式或隐式地比较
ProdCategory
实例(例如,隐式使用就是拥有
Dictionary>
)。好的-也许这是编写GetHashCode函数的更好方法(这更好的原因是什么?),但它仍然无法解释为什么最初不填充Category。它只是隐藏了事实,因为ID是0。在我的模型中,0不是有效值。@Rick未填充类别/产品的原因是您使用的是实际的
ProdCategory
,而不是
ProdCategory
的EF代理。因此EF无法将延迟加载代码注入虚拟属性getter。总的来说,依赖延迟加载导致的问题比它真正解决的问题还要多。此外,使用可能涉及到数据库往返的
GetHashCode
函数也不是很明智(
GetHashCode
应该尽可能地提高性能,这就是它的全部要点)。我也不会使用非常可能的可变数据(如外键ID)定义
GetHashCode
。。。除非
ProdID
CategoryID
都是主键,否则我只能将其保留在
ProdID
上。。。再说一次,这种设计对我来说没有意义(为什么不是每个产品都有自己的id,独立于类别?)哦,我看到这是一个关联表。。。然后可以同时使用
ProdID
CategoryID
。。。但是仅仅拥有这个关联表并没有多大意义。。。它有哪些需要的特性?为什么要“标记以删除关联”?如果是这种情况,您可以在
产品
类别
中执行此操作,只需将关联设置为
类别
产品
为空即可。使用ORM的一个要点是,您可以去掉这些“样板”表格。@Aron哦,是的,他并没有对您的答案发表评论,这正是问题的关键所在(我现在将向上投票)。。。只是质疑OP的设计决策。