Why reference properties works only through context

核能气质少年 提交于 2019-12-05 04:43:01

I solved second issue (A parameterless constructor was not found... exception) like this:

  1. I setted default constructor of Entity class and sub entities as protected
  2. When I load entity from DB Context property of entities will be null, because EF uses default constructor. That's why I created my own IQuerable collection. It sets Context property when it's not setted:

    class IContextable<T> : IQueryable<T> where T : Entity {

    public IQueryable<T> SourceQuery { get; set; }
    public KitchenAppContext Context { get; set; }
    public IContextable(IQueryable<T> query, KitchenAppContext context)
    {
        SourceQuery = query;
        Context = context;
    }
    
    public Type ElementType => SourceQuery.ElementType;
    
    public Expression Expression => SourceQuery.Expression;
    
    public IQueryProvider Provider => SourceQuery.Provider;
    
    public IEnumerator<T> GetEnumerator()
    {
        foreach (var entity in SourceQuery)
        {
            if (entity.Context == null || entity.Context != Context)
                entity.Context = Context;
            yield return entity;
        }
    }
    
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
    }
    

And my GetEntities method in my Context class:

public IQueryable<T> GetEntities<T>() where T : Entity
    {
        IQueryable<T> query = Set<T>();
        return new IContextable<T>(query, this);
    }

Maybe, there was better ways, but I couldn't found them. It works now, but I'm still waiting for good answer

When you create the OrderDetail object you have to do something with it. Currently you have only set the Order property. And that's it, EntityFramework doesn't know that this object exists so it cannot do anything with it.

To make it "known" to EntityFramework you have to add it directly or indirectly to the context. The obvious way is to add the object directly to the context as you have already said and tried:

Context.OrderDetails.Add(orderDetail);

Another way is it to add the OrderDetail object to your Order objects Details property/list. When the Order object is added to the context and it references a OrderDetail object, then saving the Order object will also "see" the OrderDetail object and save it as well. This way the OrderDetail object is added indirectly to the context. The code might look like this:

var order = new Order(Context);
var orderDetail = new OrderDetail(Context)
{
    Order = order // might not be needed
};
order.Details.Add(orderDetail);
Context.Orders.Add(order);

This will save the Order object. Additionally it will check the references and links and will see the added OrderDetail object. So it will save the OrderDetail object as well.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!