简体   繁体   English

实体框架代码第一:如何使用比模型属性少的参数映射到存储过程?

[英]Entity Framework Code First: How to map to stored procedures with less parameters than model properties?

I have a model named File with properties CreatedOn and ModifiedOn mapped to columns CreatedOn and ModifiedOn on table File. 我有一个名为File的模型,其属性CreatedOn和ModifiedOn映射到表File上的列CreatedOn和ModifiedOn。 I don't want values of these columns to be set by users instead, they will be set by using the function GETDATE() in SQL. 我不希望由用户设置这些列的值,而是使用SQL中的函数GETDATE()来设置它们。 Following is my code: 以下是我的代码:

This is my model (simplified for test): 这是我的模型(简化测试):

public class File
{
    public int? Id { get; set; }
    public DateTime? CreatedOn { get; set; }
    public string Name { get; set; }
    public DateTime? ModifiedOn { get; set; }
}

My model mapping to stored procedures: 我的模型映射到存储过程:

public class FileMap: EntityTypeConfiguration<File>
{
    public FileMap()
    {
        MapToStoredProcedures(s => s.Insert(i => i.HasName("InsertFile").Parameter(f => f.Name, "Name")));
    }
}

My migration: 我的迁移:

public partial class AddInsertStoredProcedure: DbMigration
{
    public override void Up()
    {
        CreateStoredProcedure(
            "dbo.InsertFile",
            p => new
            {
                Name = p.String(),
            },
            body:
                @"INSERT [dbo].[Files]([CreatedOn], [ModifiedOn], [Name])
                  VALUES (GETDATE(), GETDATE(), @Name)

                  DECLARE @Id int
                  SELECT @Id = [Id]
                  FROM [dbo].[Files]
                  WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()

                  SELECT t0.[Id]
                  FROM [dbo].[Files] AS t0
                  WHERE @@ROWCOUNT > 0 AND t0.[Id] = @Id"
            );
     /* ... */
}

My test class: 我的测试课:

   class Program
{
    static void Main(string[] args)
    {
        var context = new EntityContext();
        context.Files.Add(new File { Name = "File 1" });
        context.Files.Add(new File { Name = "File 2" });
        context.Files.Add(new File { Name = "File 3" });
        context.Files.Add(new File { Name = "File 4" });
        context.SaveChanges();
        Console.WriteLine("Done");
        Console.ReadLine();
    }
}

When running it I receive an exception {"Procedure or function InsertFile has too many arguments specified."}. 运行它时,我收到一个异常{“过程或函数InsertFile指定了太多参数。”}。 It seems that EF passed all the properties of my model to the stored procedure InsertFile so there were extra arguments. 似乎EF将我模型的所有属性都传递给了存储过程InsertFile,所以有一些额外的参数。 Can I have EF pass only the property Name? 我可以让EF仅传递属性Name吗?

Try adding attributes to your properties, if you don't need them in the stored procedure: 如果在存储过程中不需要属性,请尝试将其添加到属性中:

[DatabaseGenerated(DatabaseGeneratedOption.None)]

If you want to get your properties from the stored procedure use: 如果要从存储过程中获取属性,请使用:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]

and map in Fluent.api like this : 然后像这样在Fluent.api中进行映射:

    public FileMap()
    {
        MapToStoredProcedures(s => s.Insert(i => i.HasName("InsertFile").Parameter(f => f.Name, "Name").Result(f => f.ModifiedOn,"ModifiedOn"));
}

For example, this is what I'm using for this: 例如,这就是我正在使用的:

model: 模型:

public partial class Order
{
    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int MasterFID { get; set; }

    [Key]
    [Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public int ID { get; set; }

    [StringLength(50)]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public string Number { get; set; }

    public int? OutletID { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime? OrderDate { get; set; }

    [StringLength(250)]
    public string Comment { get; set; }

    public decimal? Sum { get; set; }

Fluent.Api Mapping: Fluent.Api映射:

modelBuilder.Entity<Order>()
                .MapToStoredProcedures(sp =>
                {
                    sp.Insert(i => i.HasName("web_DS_Set_DocHeaders")
                                    .Parameter(p => p.OutletID, "mfID")
                                    .Parameter(p => p.DocTypeID, "orType")
                                    .Parameter(p => p.Comment, "orComment")
                                    .Parameter(p => p.Sum, "orSum")

                                    .Result(r => r.Number, "orNumber")
                                    .Result(r => r.OrderDate,"orDate")
                                    .Result(r => r.ID, "orID"));
                });

And at the end of my stored procedure, I have something like this for return inserted row: 在存储过程的最后,我有类似以下内容用于返回插入的行:

Select orNumber, orDate, orId from Orders where --parameters for last inserted|updated row

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM