Entity framework 实体框架MapToStoredProcess-忽略参数

Entity framework 实体框架MapToStoredProcess-忽略参数,entity-framework,entity-framework-6,Entity Framework,Entity Framework 6,我们有一个db表,它有以下列 WidgetId(PK) WidgetName WidgetCreatedOn WidgetLastUpdatedOn 我们有处理小部件表上的更新/删除/插入的存储过程 Insert stored proc仅将WidgetName作为参数,例如 exec Widget_Insert @WidgetName='Foo Widget' 然后,存储过程为WidgetCreatedOn WidgetLastUpdateOn本身输入日期 小部件对象具有与表相同的属性

我们有一个db表,它有以下列

  • WidgetId(PK)
  • WidgetName
  • WidgetCreatedOn
  • WidgetLastUpdatedOn
我们有处理小部件表上的更新/删除/插入的存储过程

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

  exec Widget_Insert @WidgetName='Foo Widget'
然后,存储过程为WidgetCreatedOn WidgetLastUpdateOn本身输入日期

小部件对象具有与表相同的属性,例如

  • WidgetId(密钥)
  • WidgetName
  • WidgetCreatedOn
  • WidgetLastUpdatedOn
是否可以告诉MapToStoredProcess忽略特定属性,例如

        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**)));
modelBuilder.Entity()
.MapToStoredProcess(s=>
s、 插入(i=>i.HasName(“小部件插入”)
.Parameter(a=>a.WidgetName,“WidgetName”)
.Parameter(a=>a.WidgetCreatedOn,**不映射它**)
.Parameter(a=>a.widgetlastupdedon,**不映射它**));

我们先编写代码

虽然可能有一种方法可以手动更改MapToStoredProcedures配置来实现这一点,但我还没有发现它。话虽如此,有一种方法可以实现这一点,我认为这就是英孚希望你们做的事情

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

如果你仔细想想,这是有道理的。插入过程将从模型中获取尽可能多的信息来进行插入。但是Identity/Computed属性是指数据库将提供数据的属性,因此它不会在模型中查找该数据

这种方法需要注意的几点。EF希望这些标识/计算字段从proc返回,因此您需要在插入后进行选择(在sql server中对SCOPE_Identity()进行筛选)。EF还假设标识字段不会返回为null,因此即使您不打算稍后更新它们,也必须计算这些字段


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

任何不需要传递到映射存储过程(ever)的属性都可以标记为计算属性。只需在属性定义前面添加属性
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
。过程运行后,该过程必须返回一个包含所有“计算”值的结果集,否则将出现乐观并发错误。A
从其中选择*应该可以

如果生成了类,则可以创建一个分部类来确保所有这些属性的安全

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;

            ...
        }
    }
}

我们已经尝试过了,但正如您所指出的,EF希望存储过程返回它们,但我们只返回范围标识。最终暂时使用了EDMX