C# 实体框架6混合存储过程和SQL查询生成

C# 实体框架6混合存储过程和SQL查询生成,c#,entity-framework,stored-procedures,C#,Entity Framework,Stored Procedures,阅读CodePlex上的EF文档后,我了解到目前不可能同时使用这两种方法来持久化域模型更改 然而,有很多原因让我感到沮丧,因为它不允许我同时使用这两种语言,而它的前身LINQ2SQL允许我这样做 我有一个复杂的场景,用于将域模型持久化到数据库中的多个表,因此我希望使用存储过程进行插入。我不想使用存储过程进行更新的原因是,没有一种干净的方法可以仅在受影响的列上运行更新—将所有值解析为更新存储过程我必须更新该记录的所有字段(除非我再次选择所有旧值进行比较,或者在UPDATE语句谓词子句中包含字段——

阅读CodePlex上的EF文档后,我了解到目前不可能同时使用这两种方法来持久化域模型更改

然而,有很多原因让我感到沮丧,因为它不允许我同时使用这两种语言,而它的前身LINQ2SQL允许我这样做

我有一个复杂的场景,用于将域模型持久化到数据库中的多个表,因此我希望使用存储过程进行插入。我不想使用存储过程进行更新的原因是,没有一种干净的方法可以仅在受影响的列上运行更新—将所有值解析为更新存储过程我必须更新该记录的所有字段(除非我再次选择所有旧值进行比较,或者在UPDATE语句谓词子句中包含字段——这两种方式都有点混乱)。这是一个问题,因为触发器被附加到表中,在该表中检查各个字段的更新,这更像是一个遗留系统问题-因此,我们不会继续主观地认为使用触发器是一个好的设计

将所有字段传递到更新存储过程(即使它们没有更改)是不必要的,并且可能会导致网络流量,而EF知道在使用SQL查询生成模式时要显式更新哪些字段

是否有实体框架附加组件允许我混合使用存储过程映射进行插入,然后使用SQL查询生成进行模型持久性更新


对于我的数据库,我特别使用SQL Server,但是我相信合适的附加组件不会与我选择的数据存储耦合。

您可以调用存储过程(如果它已经在数据库中),也可以编写查询并执行它

我目前没有使用visual studio的笔记本电脑,但它应该是这样工作的:

  List<Ekipa> result = new List<Ekipa>();
        DataSet ds = new DataSet();
        using (UsersContext uc = new UsersContext())
        {
            using (SqlConnection con = new SqlConnection(uc.Database.Connection.ConnectionString))
            {
                con.Open();

                SqlCommand com = new SqlCommand("procedurename", con);
                com.CommandType = CommandType.StoredProcedure;
                 command.Parameters.AddWithValue("@id", 12);
                using (SqlDataAdapter da = new SqlDataAdapter(com))
                {
                    da.Fill(ds);
                }
            }
        }

        result = (from myRow in ds.Tables[0].AsEnumerable()
                  select new Ekipa()
                  {
                      UserId = myRow.Field<int>("UserId"),
                      UserName = myRow.Field<string>("UserName"),
                      Bodovi = myRow.Field<int>("Bod"),
                      OU = myRow.Field<int>("OU"),
                      Gol = myRow.Field<int>("PostignutiGolovi"),
                  }).ToList();
列表结果=新列表();
数据集ds=新数据集();
使用(UsersContext uc=newuserscontext())
{
使用(SqlConnection con=newsqlconnection(uc.Database.Connection.ConnectionString))
{
con.Open();
SqlCommand com=新的SqlCommand(“procedurename”,con);
com.CommandType=CommandType.StoredProcess;
command.Parameters.AddWithValue(“@id”,12);
使用(SqlDataAdapter da=newsqldataadapter(com))
{
da.填充(ds);
}
}
}
结果=(来自ds.Tables[0]中的myRow)。AsEnumerable()
选择新Ekipa()
{
UserId=myRow.Field(“UserId”),
UserName=myRow.Field(“用户名”),
Bodovi=myRow.Field(“Bod”),
OU=myRow.Field(“OU”),
Gol=myRow.Field(“PostignutiGolovi”),
}).ToList();
只需在配置中启用多个MultipleActiveResultSet

<add name="DefaultConnection" connectionString="Data Source=**.**.***.***;Initial Catalog=**;User ID=**_DBUser; Password=***; MultipleActiveResultSets=true; " providerName="System.Data.SqlClient" />

我也在找那种混合物。
DbSet
有一个名为
SqlQuery
的方法,您可以在其中放置自定义
SELECT
查询(带有一些警告)。您也可以调用存储过程。 看看这个:exmaple显示的位置:

我只是以这种方式为自己使用它:


…因为我实际上想清除我的200.000行表。它很快,上下文也正常。但是我必须包括
Select
,以维护上下文的完整性。调用
ToList()
很重要,即使我没有得到结果。

我知道我自己可以显式调用SQL,但这不是一个适用于我的数据库上下文跟踪的所有模型的可扩展解决方案。我只想让EF能够使用
SaveChanges
解决这个问题,我可以在我的CodeFirst映射中显式定义它问题是我只能将所有CUD操作映射到存储过程或所有动态生成的SQL。无法理解您试图实现的目标…您是说要更新实体而不是所有列吗?我想保留实体的更改,但只保留已更改的字段。如果我使用EF query generation then EF将仅为已更改(需要)的字段创建UPDATE语句,如果我使用存储过程映射,则EF会将实体的所有字段传递到存储过程-但我如何知道存储过程中哪些字段已更改,以便仅对已更改的字段运行UPDATE stmt-这一点很重要,因为在SQL Server中,如果使用相同的值更新列,则仍会执行底层触发器-我们有在triggersSimply中,我想使用存储过程进行实体插入,但EF查询生成用于更新(因此只有那些已更改的字段才会更新)。EF 6不允许我使用这种混合模式,因此有合适的解决方案(可能是一个附加组件)哪一个呢?我希望所有这些都通过
SaveChanges
实现,这样EF仍然可以处理所有的持久性。
using (var context = new BloggingContext()) 
{ 
    var blogs = context.Blogs.SqlQuery("dbo.GetBlogs").ToList(); 
}
db.RegistroSet.SqlQuery("DELETE FROM RegistroSET; SELECT * FROM RegistroSet").ToList();
int c = db.RegistroSet.Count();