powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
10 сообщений из 10, страница 1 из 1
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38311913
gun-gun2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!
Помогите разобраться с такой проблемой:
Есть проект на mvc3 с использованием EntityFramework4, который работает медленно и требует оптимизации. Медленно работает следующая часть проекта:
Есть товар, характеризующийся двумя типами свойств. Каждый конкретный товар может принимать одно значение для каждого из свойств.
То есть имеем следующие модели (и соответствующие таблицы в БД):

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
//Товар
public class Product
{
	public int ProductId { get; set; }
	public int PropAId { get; set; }
    public int PropBId { get; set; }
}

//Первое свойство
public class PropA
{
	public int PropAId { get; set; }
	public string PropAName { get; set; }
}

//Второе свойство
public class PropB
{
	public int PropBId { get; set; }
	public string PropBName { get; set; }
}



Так же есть клиент, которого могут удовлетворять такие товары, которые соответствуют его требованиям по данным двум свойствам. Причем у клиента может быть несколько подходящих значений как первого так и второго свойства. То есть имеем:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
//Клиент
public class Client
{
	public int ClientId { get; set; }
	public string ClientName { get; set; }
}

//Таблица подходящих значений первого свойства для клиентов
public class ClientWishA
{
	public int ClientWishAId { get; set; }
	public int ClientId { get; set; }
	public int PropAId { get; set; }
}

//Таблица подходящих значений второго свойства для клиентов
public class ClientWishB
{
	public int ClientWishBId { get; set; }
	public int ClientId { get; set; }
	public int PropBId { get; set; }
}



Суть проблемного участка кода заключается в заполнении таблицы соответствий продуктов клиентам:
Код: c#
1.
2.
3.
4.
5.
6.
public class Accord
{
	public int AccordId { get; set; }
	public int ClientId { get; set; }
	public int ProductId { get; set; }
}



С некоторых пор сервер с трудом справляется с данной задачей и на одну итерацию уходит 2 часа, что очень много. Причина, предположительно, в использовании не самой быстрой технологии EntityFramework4, в связи с чем есть желание вынести всё это дело в хранимую процедуру. Однако я совсем не знаю SQL до такой, по правде сказать, степени, что даже не знаю что мне гуглить. Понятно, что ознакомиться с соответствующей литературой было бы не лишним, однако времени сейчас на это нет - вопрос стоит остро.
В каком направлении мне хотя бы искать? Мне кажется, что это какая-то типовая задача и много где могла обсуждаться. Так ли это?

Прошу прощения за длинный пост и спасибо всем кто поможет!
...
Рейтинг: 0 / 0
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38311920
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не... причина не в EF.
...
Рейтинг: 0 / 0
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38311925
gun-gun2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Почему нет? Видел много разных тем на stackoverflow.com, где народ жаловался на тормоза, связанные именно с EF.
Ну или если не в EF проблема, то в чем тогда?
...
Рейтинг: 0 / 0
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38311931
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну... Давайте отложим до завтра... А то я могу чтонить обидное написать...
По вашему описанию совершенно непонятно что тормозит... Код покажите.
P.S.: то что Вы все-таки выложили... вызывает грусть...
...
Рейтинг: 0 / 0
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38312367
gun-gun2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если оставить только то, что имеет отношение к данному вопросу, то получится примерно так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
//Клиент
public class Client
{
	public int ClientId { get; set; }
	public string ClientName { get; set; }
	
	public virtual List<ClientWishA> ClientWishACollection { get; set; }
	public virtual List<ClientWishB> ClientWishBCollection { get; set; }
	public virtual List<Accord> AccordsCollection { get; set; }
}


IQueryable<Client> clients = from c in db.Clients select c;
							 
IQueryable<Product> products = from c in db.Products select c;
						
foreach (var client in clients)
{
	foreach (var product in products)
	{
		bool bPropsOk = false;	
		//Проверяем подходит ли продукт по первому свойству
		foreach (var curClientWishA in client.ClientWishACollection)
		{
			if (curClientWishA.PropAId == product.PropAId)
			{
				bPropsOk = true;
				break;
			}
		}
		
		if(bPropsOk)
		{
			bPropsOk = false;
			//Проверяем подходит ли продукт по второму свойству
			foreach (var curClientWishB in client.ClientWishBCollection)
			{
				if (curClientWishB.PropBId == product.PropBId)
				{
					bPropsOk = true;
					break;
				}
			}
		}
		
		//Если подходит, то проверяем не было ли такое соответствие найдено и уже добавлено в базу во время предыдущих итераций
		if(bPropsOk)
		{
			var accordsInDB = from c in client.AccordsCollection
							   where c.ProductId == product.productId
							   select c;
			var accordsInDBList = accordsInDB.ToList<Accord>();
			
			if (accordsInDBList.Count == 0)
			{
				//Добавляем найденое соответствие
				Accord newAccord = new Accord(client.ClientId, product.ProductId, false);
				db.Accords.Add(newAccord);
			}
		}
	}
}

//Сохраняем изменения
db.SaveChanges();
...
Рейтинг: 0 / 0
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38312369
gun-gun2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
buserНу... Давайте отложим до завтра... А то я могу чтонить обидное написать...
По вашему описанию совершенно непонятно что тормозит... Код покажите.
P.S.: то что Вы все-таки выложили... вызывает грусть...

Кстати что грусть то у Вас вызывает?
...
Рейтинг: 0 / 0
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38312381
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gun-gun2Причина, предположительно, в использовании не самой быстрой технологии EntityFramework4
Entity Framework тут вообще не при чем.

gun-gun2Однако я совсем не знаю SQL до такой, по правде сказать, степени, что даже не знаю что мне гуглить.
Вот в чем истинная причина.
...
Рейтинг: 0 / 0
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38312387
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема в непонимании, как работать с IQueryable и для чего оно нужно.

Код: c#
1.
2.
IQueryable<Client> clients = from c in db.Clients select c;
IQueryable<Product> products = from c in db.Products select c;



Код: c#
1.
2.
var clients = db.Clients.ToList();
var products = db.Products.ToList();
...
Рейтинг: 0 / 0
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38312401
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот это тоже печальная картина:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
if(bPropsOk)
		{
			var accordsInDB = from c in client.AccordsCollection
							   where c.ProductId == product.productId
							   select c;
			var accordsInDBList = accordsInDB.ToList<Accord>();
			
			if (accordsInDBList.Count == 0)
			{
				//Добавляем найденое соответствие
				Accord newAccord = new Accord(client.ClientId, product.ProductId, false);
				db.Accords.Add(newAccord);
			}
		}



В двойном цикле в каждой итерации при bPropsOk == true ты передергиваешь базу данных. Это не есть гуд.

Возможно, в качестве оптимизации рассмотреть инклюд (в начале):

Код: c#
1.
var products = db.Clients.Include("AccordsCollection").ToList();
...
Рейтинг: 0 / 0
Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
    #38312403
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще, скрипт создания и наполнения БД тестовыми данными в студию. А так же тестовый солюшен. Разберемся.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Помогите переписать C# код и заменить его на хранимую процедуру, чтобы избавиться от EF4
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]