Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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# EF延迟加载不工作_C#_Entity Framework_Lazy Loading - Fatal编程技术网

C# EF延迟加载不工作

C# EF延迟加载不工作,c#,entity-framework,lazy-loading,C#,Entity Framework,Lazy Loading,实体和组件具有一对多关系。实体正确存储在数据库中,包含所有组件。但当我尝试将其加载回时,子方法组件中的该实体未加载。如果我尝试使用延迟加载,entity.GetComponent上的代码将失败,因为entity.Components未初始化。初始化异常组件后,异常组件具有零个元素。如果禁用延迟加载,组件将被初始化,并且没有元素。我编写了构建一对多关系和使用惰性初始化的示例,效果很好 public static void Main(string[] args) { Parent();

实体和组件具有一对多关系。实体正确存储在数据库中,包含所有组件。但当我尝试将其加载回时,子方法组件中的该实体未加载。如果我尝试使用延迟加载,entity.GetComponent上的代码将失败,因为entity.Components未初始化。初始化异常组件后,异常组件具有零个元素。如果禁用延迟加载,组件将被初始化,并且没有元素。我编写了构建一对多关系和使用惰性初始化的示例,效果很好

public static void Main(string[] args)
{
    Parent();
    Child();
}

private static void Child()
{
    using (var db = new EntitiesContext())
    {
        var entities = from entity in db.Entities
                       select entity;

        foreach (Entity entity in entities)
        {
            Position pos = entity.GetComponent<Position>();
            Core core = entity.GetComponent<Core>();
        }
    }
}

private static void Parent()
{
    Entity entity = new Entity();

    entity.AddComponent(new Position(10, 10));
    entity.AddComponent(new ObjectName("Entity" + 1));
    entity.AddComponent(new Core(100));

    using (var db = new EntitiesContext())
    {
        db.Entities.Add(entity);
        db.SaveChanges();
    }
}

public class EntitiesContext : DbContext
{
    public DbSet<TypeMaskPair> MappedTypes { get; set; }
    public DbSet<Entity> Entities { get; set; }

    public EntitiesContext()
        : base("EntitiesDb")
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Entity>()
            .HasMany(entity => entity.Components)
            .WithRequired(component => component.EntityObj)
            .HasForeignKey(component => component.EntityId)
            .WillCascadeOnDelete();

        //this.Configuration.LazyLoadingEnabled = false;
    }
}

public abstract class Component
{
    [Key]
    public int Id { get; set; }
    [Required]
    public int EntityId { get; set; }
    [Required]
    public virtual Entity EntityObj { get; set; }

    private static DbMasksMapper componentsMap;

    static Component()
    {
        componentsMap = new DbMasksMapper(typeof(Component));
    }

    public TypeMask GetMask()
    {
        return componentsMap.GetMask(this.GetType());
    }

    public static TypeMask GetMask<T>() where T : Component
    {
        return componentsMap.GetMask(typeof(T));
    }
}

public class Entity
{
    [Key]
    public int Id { get; set; }

    public virtual List<Component> Components { get; set; }

    [NotMapped]
    public TypeMask Mask { get; private set; }

    public string TypeMaskString
    {
        get{ return Mask.ToString(); }
        set{ Mask = new TypeMask(value); }
    }

    public Entity()
    {
        Components = new List<Component>();
        Mask = new TypeMask();
    }

    public void AddComponent(Component component)
    {
        Components.Add(component);
        component.EntityObj = this;
        Mask |= component.GetMask();
    }

    public void DeleteComponent(TypeMask componentMask)
    {
        if (ContainsComponent(componentMask))
        {
            int removeIndex = Components.FindIndex(c => c.GetMask() == componentMask);
            Components.RemoveAt(removeIndex);
            Mask &= ~componentMask;
        }
    }

    public Component GetComponent(TypeMask componentMask)
    {
        return Components.Find(c => c.GetMask() == componentMask);
    }

    public T GetComponent<T>() where T : Component
    {
        return (T) GetComponent(Component.GetMask<T>());
    }

    public bool ContainsComponent<T>() where T : Component
    {
        return ContainsComponent(Component.GetMask<T>());
    }

    public bool ContainsComponent(TypeMask componentMask)
    {
        return (Mask & componentMask) == componentMask;
    }
}

class Position : Component
{
    public Position(int x = 0, int y = 0)
    {
        X = x;
        Y = y;
    }

    public int X { get; set; }
    public int Y { get; set; }
}

class Cargo : Component
{
    public Cargo(int capacity = 0)
    {
        Capacity = capacity;
    }

    public int Capacity { get; set; }
}

class Core : Component
{
    public Core(int power = 0)
    {
        Power = power;
    }

    public int Power { get; set; }
}

class ObjectName : Component
{
    public ObjectName(string name = "")
    {
        Name = name;
    }

    public string Name { get; set; }
}
我看到了类似的问题,但没有找到任何答案

哪里有错误

解决方案


在我为继承的组件编写默认构造函数之后,所有这些都可以正常工作。但是,我不明白为什么带有默认参数的构造函数不合适。没有任何参数,它应该像默认构造函数一样工作。有人能解释一下吗?似乎我做错了

,因为EF需要为子实体创建代理类,如果没有公共或受保护的无参数构造函数,它就无法做到这一点。更多信息:@AlaaMasoud,我知道。我不明白为什么带有默认参数的构造函数不能像无参数构造函数那样工作?因为EF不知道为这些参数传递什么。@AlaaMasoud,所以它不会像在C/C++中那样展开为单独的构造函数防御?默认参数值只是一个技巧。当编译器生成调用时,它将在调用方端提供默认值。因此,在编译之后,就不再有默认的参数值了——所有的参数值都会被传递。因此,具有默认参数的系数不等于无参数系数。