EntityFramework CodeFirst和EDMX一起在TransactionScope中

时间:2012-10-12 17:57:13

标签: c# entity-framework ef-code-first msdtc

我需要在一个应用程序中合并

  1. 编译前从DB到EDMX文件生成的代码和
  2. 在运行时由应用程序本身生成和编译的代码,其中生成的代码使用CodeFirst访问DB。
  3. 备注:1和2中的代码具有不同的DbContexts,访问相同的数据库,但不同的表。

    看起来,当我在不同的事务范围中使用类型1和2.的实例时,一切正常。但是当我尝试在一个事务范围内一起使用它们时,我得到错误(如果首先调用EDMX)

    System.Reflection.TargetInvocationException: Exception has been thrown by the ta
    rget of an invocation. ---> System.Data.ProviderIncompatibleException: An error
    occurred while getting provider information from the database. This can be cause
    d by Entity Framework using an incorrect connection string. Check the inner exce
    ptions for details and ensure that the connection string is correct. ---> System
    .Data.ProviderIncompatibleException: **The provider did not return a ProviderManif
    estToken string.** ---> System.Transactions.TransactionException: **The operation is
     not valid for the state of the transaction.**
    

    和错误(如果首先使用CodeFirst)

    System.Data.MetadataException: Schema specified is not valid. Errors:
    (0,0) : error 0175: **The specified store provider cannot be found in the configur
    ation, or is not valid.**
       at System.Data.Metadata.Edm.StoreItemCollection.Loader.ThrowOnNonWarningErrors()
    

    为了使我的情况更加复杂,我必须添加这个:描述的行为我只有在DB在远程服务器上时才有。如果我使用本地数据库,一切看起来都不错。我怀疑分布式事务协调员可以发挥其作用......

    主要问题:是否可以在一个TransactionScope中结合使用EDMX和CodeFirst。如果是,那么如何?

    任何帮助将不胜感激。米洛斯

2 个答案:

答案 0 :(得分:0)

CodeFirst会根据您的类创建EDMX,并且无法加载现有的edmx文件。但是,您可以从数据库生成类(例如,使用EF Power Tools)并配置模型,以便CodeFirst应用程序生成的EDMX与您要加载的EDMX相同。您可以将TransactionScope与Entity Framework一起使用。您获得的错误消息与事务范围无关,但与缺少或错误使用的提供程序无关。

答案 1 :(得分:0)

我首先使用代码保存到两个不同的数据库,出现错误连接字符串错误,所以我这样做了,它工作....

try
{
    using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        MegaBotExtractorDBContext2 db = new MegaBotExtractorDBContext2();
        MegaBotExtractorDBContext db1 = new MegaBotExtractorDBContext();
        FullUri newUri = new FullUri();
        HostUri NewHostUri = new HostUri { HostUriName = "google10.com" };
        db1.HostUris.Add(NewHostUri);
        db1.SaveChanges();

        using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.RequiresNew))
        {
            db.FullUris.Add(newUri);
            db.SaveChanges();
            ts2.Complete();
            ts.Complete();
        }
    }
}
catch { }