我们有一个包含以下列的数据库表。
我们有存储过程来处理Widget表上的更新/删除/插入。
Insert stored proc将只是 WidgetName作为参数,例如
exec Widget_Insert @WidgetName='Foo Widget'
然后存储过程将日期放入WidgetCreatedOn WidgetLastUpdatedOn本身。
Widget对象具有与表相同的属性,例如
是否可以告诉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
答案 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;
...
}
}
}