EF懒惰加载不起作用

时间:2014-10-19 10:45:59

标签: c# entity-framework lazy-loading

实体和组件具有一对多关系。与所有组件一起正确存储在db中的实体。但是当我尝试加载它时,这个Entity in Child方法组件不会加载。如果我尝试使用延迟加载,由于Entity.Components未初始化,因此实体.GetComponent上的代码失败。异常组件初始化后,元素为零。如果我禁用延迟加载,则会初始化组件并且元素为零。我写了一个用于构建一对多关系并使用延迟初始化的示例,它工作正常。

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; }
}

我看到了类似的问题,但没有找到任何答案。

哪里出错?

解决方案

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

0 个答案:

没有答案