首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >一种简单的方法,可以在覆盖delete时神奇地生成更新和插入存储过程

一种简单的方法,可以在覆盖delete时神奇地生成更新和插入存储过程
EN

Stack Overflow用户
提问于 2013-05-16 04:40:15
回答 2查看 904关注 0票数 0

在当前版本之前,我已经有一段时间没有为我的实体类创建特殊的存储过程了。然后它被放在小桌子上。我创建了我的delete,非常好,但是我忘记了EF也会让你创建插入和更新。有没有人知道一种快速的方法?我有大约7-8个表,每个表大约有30-50列,我需要这样做,而不是期待打字。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-16 05:35:21

在SSMS工具中,CRUD存储过程的创建非常棒(也是众多特性之一)。http://www.ssmstoolspack.com/

票数 2
EN

Stack Overflow用户

发布于 2013-05-16 05:43:21

,然后是在较小的桌子上。我创建了我的delete,非常好,但是我忘记了EF让您创建插入和更新的以及

您在EntityFramework 5.0中添加了这个问题,所以我不太理解为什么需要为delete生成存储过程。

所有的CRUD (创建、读取、删除、更新)都是在DbContext上完成的,不需要为此编写过程。如果你有一个组织良好的数据库(有PKs,FKs和良好的索引),你就不需要有存储过程,因为你甚至可以编译EF的视图,这样你就可以得到更好的结果。

请参阅示例代码:

代码语言:javascript
运行
复制
    DbContext context = new YourContext();

    public bool Delete<TEntity>(TEntity entity) where TEntity : class
    {
        var set = context.Set<TEntity>();
        set.Attach(entity);
        return true;
    }

    public bool Add<TEntity>(TEntity entity) where TEntity : class
    {
        var set = context.Set<TEntity>();
        set.Add(entity);
        return true;
    }

您甚至不需要使用这种方法,您可以直接使用DbContext.Set,如下例所示:

代码语言:javascript
运行
复制
    void Run()
    {

        using (DbContext context = new MyContext())
        {
            //Create a new person to insert
            var newItem = new Person() { Name = "Mike"} ;

            var set = context.Set<Person>();
            set.Add(newItem);

            // Returns a record from database with PK = "John"
            var itemToDelete = set.Find("John");
            set.Remove(itemToDelete);

            // This will add the new record, and delete "John" from the Database
            context.SaveChanges();
        }
    }

所以您可以看到,CRUD不需要存储过程!

将存储过程用于其他内容,与数据库相关,不需要使用EF :)

有人知道一个快速的方法吗?我有大约7-8个表,每个表中有大约30-50列,我需要这样做,而不是期待输入。

这里要说明的是,在使用EF时,您不需要编写存储过程来处理CRUD操作。

你问我一种快速的方法(甚至提到你不想输入它们),我的回答是:

更快的方法是不做任何程序!这很快,而且可以避免键入! :)

演示的代码已经处理了您的需求,而不需要任何存储过程。:)

添加了信息

如果您认为需要删除存储过程的原因是您想要删除相关实体,并且您认为EF不处理此站点,则这是另一个问题,我可以告诉您一些可能的原因:

1)可能因为FK引用而以错误结束,这种情况下,请看一下here

2)错误可能是因为当您从与其他实体的关系中移除一个实体时,EF不会理解您想要逻辑删除该记录,您需要额外地将.ChangeState更改为Deleted。

请看下面这个例子:

代码语言:javascript
运行
复制
public static void StudentLeaves(string name)
{
    using (var context = new SchoolContext())
    {
        context.Students.Remove(context.Students.Single(s => s.Name == name));
        context.SaveChanges();
    }
}

上面的例子会删除这个学生,对吗?但是现在看看第二个例子

代码语言:javascript
运行
复制
public static void StudantLeaveParticularSchool(string schoolName, string name)
{
    using (var context = new SchoolContext())
    {
        var school = context.Schools.Single(a => a.Nome == schoolName);
        school .Students.Remove(context.Students.Single(a => a.Nome == name));
        context.SaveChanges();
    }
}

下面的代码不会从数据库中删除学生,它只会删除关系!

如果您使用的是CodeFirst,您可以明确表示您想要使用DeleteCascade,如下所示:

代码语言:javascript
运行
复制
modelBuilder
    .Entity()
    .HasRequired(s => s.Schools)
    .WithMany(r => r.Students)
.WillCascadeOnDelete();

更新:

对于那些对创建存储过程有“魔力”方式感兴趣的人,我将告诉你一种方法,但我再次告诉你:如果你正在使用EF和最佳实践,没有必要这样做,当我第一次开始使用EF进行开发时,我也认为我需要这样做,所以我们编写了几个T4文件,在转眼间就生成了数百个存储过程。但经过一段时间后,我们发现这不是使用EF的正确方法,所以我们放弃了过程,并将T4从项目中删除,事情变得容易得多。

要创建这些过程,您需要编写T4文件。如果你想了解更多关于T4的信息,可以在这里找到(http://msdn.microsoft.com/en-us/library/vstudio/bb126247.aspx)

我将向您展示我们编写的DELETE creation T4模板(您还需要一些其他的基本.tt文件才能运行,因此请记住,这只是一个示例):

代码语言:javascript
运行
复制
<#@ template language="C#" debug="true" #>
<#@ output extension=".sql" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.XML" #>
<#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #>
<#@ assembly name="Microsoft.SqlServer.Smo" #>
<#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="Microsoft.SqlServer.Management.Smo" #>
<#@ import namespace="Microsoft.SqlServer.Management.Common" #>
<#@ import namespace="System.Runtime.Remoting.Messaging" #>
-- Winsys Solutions
-- Stored Procedure de delete para a tabela <#= this.SchemaName #>.<#= this.TableName #>
CREATE PROCEDURE <#= this.SchemaName #>.<#= this.TableName.Replace("TBWS4_", "PRWS4_") #>_Delete
    <# WriteParameterDeclarations(this.Table); #> 
AS
BEGIN
    DELETE FROM 
        <#= this.SchemaName #>.<#= this.TableName #> 
    WHERE
        <# WriteWhereClause(this.Table); #> 
END
GO
<#@ include file="CommonSqlHelper.tt" #>

<#+
    /// <summary>
    /// Writes stored procedure parameter declarations for all columns in the 
    /// primary key and all TIMESTAMP columns of the specified table. 
    /// </summary>
    void WriteParameterDeclarations(Table table)
    {
        PushIndent("    ");
        int parameterIndex = 0;
        foreach(Column column in table.Columns)
        {
            if (column.InPrimaryKey || column.DataType.SqlDataType == SqlDataType.Timestamp)
            {
                if (parameterIndex > 0)
                    WriteLine(",");
                Write("@{0} {1}", column.Name, GetDataTypeDeclaration(column.DataType));
                parameterIndex++;
            }
        }
        PopIndent();
    }
#>

<#+
    string TableName
    {
        get { return (string) CallContext.GetData("DeleteStoredProcedure.TableName"); }
    }

    string SchemaName
    {
        get { return (string) CallContext.GetData("DeleteStoredProcedure.SchemaName"); }
    }

    Table Table
    {
        get { return (Table) CallContext.GetData("DeleteStoredProcedure.Table"); }
    }
#>

辅助方法包括:

代码语言:javascript
运行
复制
/// <summary>
/// Returns a string that contains T-SQL declaration for the specified data 
/// type. For string data types this includes maximum length, for numeric 
/// data types this includes scale and precision.
/// </summary>
string GetDataTypeDeclaration(DataType dataType)
{
    string result = dataType.Name;
    switch(dataType.SqlDataType)
    {
        case SqlDataType.Binary:
        case SqlDataType.Char:
        case SqlDataType.NChar:
        case SqlDataType.NVarChar:
        case SqlDataType.VarBinary:
        case SqlDataType.VarChar:
            result += string.Format("({0})", dataType.MaximumLength);
            break;

        case SqlDataType.NVarCharMax:
        case SqlDataType.VarBinaryMax:
        case SqlDataType.VarCharMax:
            result += "(max)";
            break;

        case SqlDataType.Decimal:
        case SqlDataType.Numeric:
            result += string.Format("({0}, {1})", dataType.NumericPrecision, dataType.NumericScale);
            break;
    }
    return result;
}

/// <summary>
/// Generates where clause for UPDATE and DELETE statements for the specified
/// table.
/// </summary>
void WriteWhereClause(Table table, bool includeAllColumns = false)
{
    PushIndent("        ");
    int whereIndex = 0;
    foreach(Column column in table.Columns)
    {
        if (column.InPrimaryKey || column.DataType.SqlDataType == SqlDataType.Timestamp || includeAllColumns)
        {
            if (whereIndex > 0)
                WriteLine(" AND");

            if (includeAllColumns)
                Write("({0} = @{0} OR @{0} IS NULL)", column.Name);
            else
                Write("{0} = @{0}", column.Name);

            whereIndex++;           
        }
    }
    PopIndent();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16574566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档