实体框架附加对象但不调用SaveChanges

时间:2015-12-08 13:36:21

标签: c# .net entity-framework

下面是一个示例代码,它应该展示我正在努力实现的目标:

    public static void addRecord(CargoShip ship, DbContext db)
    {
        // Realistically, in my application this is decided by business logic, - omitted for brevity
        long containerTypeIDNewContainer = 5;

        Container containerToAdd = new Container()
        {
            cargoShipBelongingToID = ship.cargoShipID,
            containerTypeID = containerTypeIDNewContainer
        };
        ship.Containers.Add(containerToAdd);

        // This line of code is what I want to be able to do
        // WITHOUT doing a db.SaveChanges

        // ContainerType is a lookup table in the database, each container type has pre-defined
        // Height/Width etc

        // This throws a null exception, ContainerType object does not exist.
        string containerHeight = containerToAdd.ContainerType.Height;
    }

我基本上希望能够创建一个新的Container并在该对象上填写外键,并能够将代码中的外键子项作为对象访问。

如果我调用SaveChanges,它自然会去获取Container对象的值,但我想填写那些值/对象而不必进行Savechanges。

修改

忘了提一下,目前尚不清楚。关系是:CargoShip有多个ContainerContainer有一个ContainerType,这是一个FK且不可为空。

你能帮忙吗?

由于

2 个答案:

答案 0 :(得分:1)

EF将为您填写所有FK属性,因为您在实体中设置了ID。只有在致电SaveChanges后才会设置这些属性。

出于这个原因,调用Add没有太大意义,除非你确实打算在某个时候打电话给SaveChanges

如果您只想获得相应的ContainerType,那么您也可以执行Select(或Find) - 这最终归结为与EF相同的SQL查询无论如何都必须在幕后使用:

var containerType = db.ContainerTypes.Find(containerTypeIdNewContainer);

请注意,如果本地缓存中尚不存在特定的Find记录,则containerType方法将仅转到数据库。但是,本地缓存的生命周期与DbContext的生命周期有关,因此可能非常短。

如果它们相对稳定,维护自己的常用实体缓存可能是有意义的:

var containerTypes = db.ContainerTypes.ToDictionary(x => x.Id, x => x);

...

var containerType = containerTypes[containerTypeIdNewContainer];

答案 1 :(得分:0)

假设您可以访问您的DbContext(不熟悉EntityFrameworkConnection类),那么您只需使用IQueryable。

IQueryable<T> query = db.Set<ContainerType>()

var containerType =  query.FirstOrDefault(x => x.containerTypeID == containerTypeIDNewContainer)

string containerHeight = containerType.Height;

希望我能正确理解你的问题