SQL, сгенерированный LINQ для ведения журнала - PullRequest
2 голосов
/ 02 сентября 2010

У меня есть этот запрос и его результат реализует IEnumerable.

RoutesEntities routesModel = new RoutesEntities();
LocalesEntities localesModel = new LocalesEntities();

var routesQuery = from rs in routesModel.Routes.ToList()
                  join ls in localesModel.Locales.ToList() 
                  on rs.LocaleID equals ls.LocaleID
                  select new
                  {
                      LocaleID = rs.LocaleID,
                      RouteName = rs.RouteName
                  };

Вопрос : Как получить сгенерированный SQL из этого запроса или как преобразовать его тип в ObjectQuery, чтобы использовать routesQuery.ToTraceString()? Возможно ли это?

Причина : Я хочу записать все запросы SQL в БД, хотя я не хочу создавать новый объект для объединенных контекстов (таблиц)

Важно : изначально я не могу использовать ObjectQuery, потому что в конце концов я использую

ListView.DataSource = routesQuery;
ListView.DataBind() 

И это может привести к ошибке использования в разных контекстах (таблицах БД) для одного источника данных.

Так что мне делать, чтобы получить сгенерированный SQL-запрос?

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 03 сентября 2010
var routesQuery = from rs in routesModel.Routes.ToList() 
                  join ls in localesModel.Locales.ToList()  

При настройке этого запроса вы загружаете всю таблицу Routes в память, а также загружаете всю таблицу Locales в память.Ваши запросы (их два) выглядят так:

select fieldlist
from tablename

Вы должны разделить два запроса на отдельные экземпляры ObjectQuery и зарегистрировать их по отдельности.Но более того, вам не следует читать нефильтрованное содержимое таблицы в память!

0 голосов
/ 21 сентября 2010

Есть ответ:

http://arteinvolo.org.ua/2010/09/21/how-to-use-entity-framework-with-multiple-entities/

public static EntityConnection setSchema(string[] edmxFiles) 
{
            XNamespace edmxns = "http://schemas.microsoft.com/ado/2007/06/edmx";
            XNamespace edmns = "http://schemas.microsoft.com/ado/2006/04/edm";
            XmlDocument edmxXml = new XmlDocument();
            XmlNamespaceManager nameSpace = new XmlNamespaceManager(edmxXml.NameTable);

            List<XmlReader> ssdlReader = new List<XmlReader>();
            List<XmlReader> csdlReader = new List<XmlReader>();
            List<XmlReader> mslReader = new List<XmlReader>();

            foreach (string edmxFile in edmxFiles)
            {
                edmxXml.Load(edmxFile);
                nameSpace.AddNamespace("edmx", edmxns.NamespaceName);

                XmlNode ssdlNode = edmxXml.SelectSingleNode("//edmx:StorageModels", nameSpace);
                XmlNode csdlNode = edmxXml.SelectSingleNode("//edmx:ConceptualModels", nameSpace);
                XmlNode mslNode = edmxXml.SelectSingleNode("//edmx:Mappings", nameSpace);

                ssdlReader.Add(XmlReader.Create(new StringReader(ssdlNode.InnerXml)));
                csdlReader.Add(XmlReader.Create(new StringReader(csdlNode.InnerXml)));
                mslReader.Add(XmlReader.Create(new StringReader(mslNode.InnerXml)));
            }

            StoreItemCollection storageCollection = new StoreItemCollection(ssdlReader);
            EdmItemCollection edmCollection = new EdmItemCollection(csdlReader);
            StorageMappingItemCollection mappingCollection = new StorageMappingItemCollection(edmCollection, storageCollection, mslReader);

            MetadataWorkspace workSpace = new MetadataWorkspace();
            workSpace.RegisterItemCollection(storageCollection);
            workSpace.RegisterItemCollection(edmCollection);
            workSpace.RegisterItemCollection(mappingCollection);

            SqlConnection metaConnect = new SqlConnection(ConfigurationManager.ConnectionStrings["CustomSqlConnection"].ToString());
            EntityConnection entityConnect = new EntityConnection(workSpace, metaConnect);

            return entityConnect;
}

Как использовать:

EntityConnection entityConnection = Connector.setSchema(new string[] {
                Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + "/App_Model/RoutesModel.edmx"),
                Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + "/App_Model/LocalesModel.edmx")
});

entityConnection.Open();
String queryData = "SELECT rs.RouteID, rs.RouteURL, ls.LocaleName, ls.IsActive, ls.LocaleDescription FROM RoutesEntities.Routes AS rs INNER JOIN LocalesEntities.Locales AS ls ON ls.LocaleID = rs.LocaleID";
EntityCommand queryCommand = new EntityCommand(queryData, entityConnection);
DbDataReader routesReader = queryCommand.ExecuteReader(CommandBehavior.SequentialAccess);

ListView.DataSource = routesReader;
ListView.DataBind();
0 голосов
/ 03 сентября 2010

Вы используете два разных контекста данных, поэтому вы будете выполнять разные запросы для каждого и присоединять результат к клиенту. Запросы в базе данных могут быть зарегистрированы, как уже было указано Femaref, для контекстов LINQ-to-SQL. EF ObjectContext по-прежнему нужно работать, чтобы догнать LINQ-to-SQL, и не предлагает ведение журнала. Однако ObjectQuery.CommandText возвращает текст запроса. Регистрация в клиенте не может быть зарегистрирована, так как ... она не существует. Это не SQL-запрос, это цикл LINQ-to-Objects.

...