实体框架MapToStoredProcedures - 忽略参数

时间:2015-01-29 15:11:53

标签: entity-framework entity-framework-6

我们有一个包含以下列的数据库表。

  • WidgetId(PK)
  • WidgetName
  • WidgetCreatedOn
  • WidgetLastUpdatedOn

我们有存储过程来处理Widget表上的更新/删除/插入。

Insert stored proc将只是 WidgetName作为参数,例如

  exec Widget_Insert @WidgetName='Foo Widget'

然后存储过程将日期放入WidgetCreatedOn WidgetLastUpdatedOn本身。

Widget对象具有与表相同的属性,例如

  • WidgetId(Key)
  • WidgetName
  • WidgetCreatedOn
  • WidgetLastUpdatedOn

是否可以告诉MapToStoredProcedures忽略特定属性,例如

        modelBuilder.Entity<Widget>()
            .MapToStoredProcedures(s =>
                s.Insert(i => i.HasName("Widget_Insert")
                      .Parameter(a => a.WidgetName, "WidgetName")
                      .Parameter(a => a.WidgetCreatedOn, **dont map it**)
                      .Parameter(a => a.WidgetLastUpdatedOn, **dont map it**)));

我们正在做Code-First

2 个答案:

答案 0 :(得分:1)

虽然可能有办法手动更改MapToStoredProcedures配置来执行此操作,但我还没有发现它。话虽如此,有一种方法可以实现这一点,我假设是EF希望你做的事情。

在模型映射中,指定Identity或Computed的DatabaseGeneratedOption将阻止将该属性发送到插入过程。

如果你考虑一下,这是有道理的。插入过程将尽可能多地从模型中获取信息以进行插入。但是,身份/计算属性就是您所说的数据库将提供数据,因此它不会查看该数据的模型。

这种方法需要注意几点。 EF将期望那些Identity / Computed字段从proc返回,因此您在插入后需要一个select(在sql server中对SCOPE_IDENTITY()进行过滤)。 EF还假设标识字段不会返回为空,因此即使您不打算稍后更新它们,也必须进行计算。

如果这些都不合适,那么在EF5中执行此类操作的方式(并且更灵活一点)是在上下文中覆盖SaveChanges并在类型为Widget时调用proc并且是EntityState.Added。或者您可以抛出异常来强制开发者使用EF的DBSet Add方法自行调用proc。

答案 1 :(得分:0)

任何不需要传递给映射存储过程(永远)的属性都可以标记为已计算。只需在属性定义前添加属性[DatabaseGenerated(DatabaseGeneratedOption.Computed)]即可。 proc必须在程序运行后返回带有所有“计算”值的结果集,否则会出现乐观并发错误。 Select * from where应该没问题。

如果生成了类,则可以进行部分类以保证所有这些属性的安全。

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MyEfNamespace
{

    [MetadataType(typeof(MetaData))]
    public partial class Widget
    {
        public class MetaData
        {
            [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
            public System.DateTime WidgetCreatedOn;

            [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
            public System.DateTime WidgetLastUpdatedOn;

            ...
        }
    }
}