Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Scully
0 / 0 / 1
Регистрация: 21.05.2014
Сообщений: 26
1

[Entity Framework] Как реализовать проверку того, есть ли уже проверяемая новость в базе?

28.05.2017, 23:23. Просмотров 895. Ответов 13
Метки нет (Все метки)

Доброго времени суток!

Я делаю парсер, который получает данные из раздела новостей сайта (заголовок новости, текст и дата публикации новости). Эти данные должны записываться при помощи Entity Framework. Если текущая новость уже существует в базе - повторная запись не производится.

Как мне реализовать проверку того, есть ли уже проверяемая новость в базе? И как осуществяется запись через Entity Framework?

Я написал программу, которая создаёт подключение к БД и записывает данные в существующую таблицу (но нужно реализовать при помощи Entity Framework).
исходник
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using System.Threading;
using HtmlAgilityPack;
using System.Data.Entity;
 
namespace e1
{
    public class News
    {
        public int id { get; set; }
        public string header { get; set; }
        public string text { get; set; }
        public string date { get; set; }
    }
 
    class NewsContext : DbContext
    {
        public NewsContext() : base("DbConnection")
        { 
 
        }
        public DbSet<News> Newes { get; set; }
    }
 
    class Program
    {
        static void Main()
        {
            using (NewsContext db = new NewsContext())
            {
                News[] tn = new News[1000];
                int counter = 0;
                HtmlWeb ws = new HtmlWeb();
                ws.OverrideEncoding = Encoding.Default;
                HtmlDocument mp = ws.Load("http://www.e1.ru/news/spool");
 
                foreach (HtmlNode link in mp.DocumentNode.SelectNodes("//table[@cellpadding = '2']//a[@class = 'news']"))
                {
                    string nlink = link.GetAttributeValue("href", "");
                    //Console.WriteLine(nlink);
                    HtmlDocument np = ws.Load("http://www.e1.ru" + nlink);
                    nlink = np.DocumentNode.SelectSingleNode("//a[@title = 'версия для печати']").GetAttributeValue("href", "");
                    //Console.WriteLine(nlink);
                    HtmlDocument pp = ws.Load("http://www.e1.ru" + nlink);
                    string header = pp.DocumentNode.SelectSingleNode("//h1").InnerText;
                    Console.WriteLine(header);
                    foreach (HtmlNode t in pp.DocumentNode.SelectNodes("//p[not(@class) and not(@align)]"))
                    {
                        Console.WriteLine(t.InnerText);
                    }
                    //string text = pp.DocumentNode.SelectSingleNode("//p").InnerText;
                    //Console.WriteLine(text);
                    Thread.Sleep(1000);
                    Console.WriteLine(counter + ": " + link.InnerText);
                }
 
                foreach (HtmlNode link in mp.DocumentNode.SelectNodes("//table[@cellpadding = '2']//a[@class = 'news']"))
                {
                    Thread.Sleep(1000);
                    counter += 1;
                    tn[counter].header = link.InnerText;
                    Console.WriteLine(counter + ": " + link.InnerText);
                }
 
                counter = 0;
 
                foreach (HtmlNode link in mp.DocumentNode.SelectNodes("//table[@cellpadding = '2']//span[@class = 'small_gray']"))
                {
                    Thread.Sleep(1000);
                    counter += 1;
                    tn[counter].date = link.InnerText;
                    Console.WriteLine(counter + ": " + link.InnerText);
                }
 
                for (int i = 1; i < 41; i++)
                {
                    db.Newes.Add(tn[i]);
                }
                Thread.Sleep(900000);
            }
            Main();
        }
    }
}


Заранее благодарен за ответ.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.05.2017, 23:23
Ответы с готовыми решениями:

Подскажите, как реализовать проверку того, что пользователь с консоли вводит ИМЕННО предложение, то есть, если
Подскажите, как реализовать проверку того, что пользователь с консоли вводит ИМЕННО предложение, то...

Как определить в Entity Framework, что модель не соответствует подключенной базе данных
Создал модель на основе базы данных. На сервере имеются несколько идентичных ей. Пользователь имеет...

Formsroleauth: как это реализовать если я использую Entity Framework 4.0
Подскажите пожалуйста как это реализовать если я использую Entity Framework 4.0...

Есть ли аналог в Entity Framework метода Contain() как Linq to Sql
например, чтобы в Linq отфильтровать в таблице по полю Name все строки, в которых есть наличие...

Подключение к другой базе и Entity Framework
Доброго времени суток. Крайне внезапно настиг вопрос с настройкой простейшего интернет магазина....

13
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
29.05.2017, 06:03 2
Цитата Сообщение от Scully Посмотреть сообщение
Как мне реализовать проверку того, есть ли уже проверяемая новость в базе? И как осуществяется запись через Entity Framework?
Можно почитать учебник по EF. Там всё есть. С картинками.
0
_exp10der_
Warrior
491 / 418 / 177
Регистрация: 23.11.2014
Сообщений: 932
30.05.2017, 11:05 3
C#
1
db.Newes.Any(n => n.Id == myIdForFind);
https://msdn.microsoft.com/en-us/lib...yable.any.aspx
0
Scully
0 / 0 / 1
Регистрация: 21.05.2014
Сообщений: 26
31.05.2017, 21:17  [ТС] 4
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using System.Threading;
using HtmlAgilityPack;
using System.Data.Entity;
 
namespace e1
{
    public class News
    {
        public int id { get; set; }
        public string name { get; set; }
        public string text { get; set; }
        public string date { get; set; }
        public bool urfu { get; set; }
    }
 
    class NewsContext : DbContext
    {
        public NewsContext() : base("DbConnection")
        { 
 
        }
        public DbSet<News> Newes { get; set; }
    }
 
    class Program
    {
        static void Main()
        {
            using (NewsContext db = new NewsContext())
            {
                int counter = 0;
                HtmlWeb ws = new HtmlWeb();
                ws.OverrideEncoding = Encoding.Default;
                HtmlDocument mp = ws.Load("http://www.e1.ru/news/spool");
 
                foreach (HtmlNode link in mp.DocumentNode.SelectNodes("//a[@class = 'e1-article__link e1-article__link_inline']"))
                {
                    string nlink = link.GetAttributeValue("href", "");
                    HtmlDocument np = ws.Load("http://www.e1.ru" + nlink);
 
                    string rawdate = np.DocumentNode.SelectSingleNode("//span[@class = 'small_gray']").InnerText;
 
                    Console.WriteLine(rawdate);
 
                    nlink = np.DocumentNode.SelectSingleNode("//a[@title = 'версия для печати']").GetAttributeValue("href", "");
                    //Console.WriteLine(nlink);
                    HtmlDocument pp = ws.Load("http://www.e1.ru" + nlink);
                    string header = pp.DocumentNode.SelectSingleNode("//h1").InnerText;
                    Console.WriteLine(header);
                    string rawtext = "";
 
                    foreach (HtmlNode t in pp.DocumentNode.SelectNodes("//p[not(@class) and not(@align)]"))
                    {
                        rawtext = rawtext + t.InnerText;
                    }
 
                    Console.WriteLine(rawtext);
 
                    if (rawtext.Contains("УрФУ") || rawtext.Contains("Уральский федеральный университет") || rawtext.Contains("Уральского федерального университета"))
                    {
                        News story = new News { name = header, text = rawtext, date = rawdate, urgu = true };
                        db.Newes.Add(story);
                    }
 
                    else
                    {
                        News story = new News { name = header, text = rawtext, date = rawdate, urfu = false };
                        db.Newes.Add(story);
                    }
 
                    Thread.Sleep(1000);
                    db.SaveChanges();
                }
 
                counter = 0;
 
                Thread.Sleep(900000);
            }
            Main();
        }
    }
}
Решил сделать так. В Add не вбиваю Id, ибо в SQLMS в таблице указал, что приращение идёт самостоятельно. Плюс, решил поиск по ключевым словам сделать сразу же, и в базе просто помечать нужные новости.

Данные парсит какие нужно НО проблема с записью - по окончании парсинга первой новости она должна была записаться, но этого не произошло (проверил таблицу в SQLSM - пусто). Что я делаю не так?
0
31.05.2017, 21:17
Scully
0 / 0 / 1
Регистрация: 21.05.2014
Сообщений: 26
02.06.2017, 23:59  [ТС] 5
Кто-нибудь?
0
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
03.06.2017, 11:08 6
Что?
0
Scully
0 / 0 / 1
Регистрация: 21.05.2014
Сообщений: 26
03.06.2017, 11:11  [ТС] 7
Usaga, не могу понять, почему не сохраняет данные в БД.

db.SaveChanges(); есть, а когда через SQL Management Studio захожу в БД - в таблице пусто.
0
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
03.06.2017, 11:17 8
Scully, а если повыкидывать из программы вообще всё и оставить только добавления в БД сущности?
0
Scully
0 / 0 / 1
Регистрация: 21.05.2014
Сообщений: 26
03.06.2017, 11:51  [ТС] 9
Usaga, а что от этого изменится? Данные парсит как нужно - и это видно, судя по тому, что их выводит на консоль.

Единственное, в чём я сомневаюсь, это то, что bool "urfu" я указал как bit "urfu" в самой таблице (в MS SQL Management Studio нет типа данных bool). Может из-за этого быть ошибка записи или ещё что?

Однако, ошибок при выполнении не выскакивает никаких. Просто не записывает в БД.
0
Scully
0 / 0 / 1
Регистрация: 21.05.2014
Сообщений: 26
04.06.2017, 20:48  [ТС] 10
Я разобрался с этим. В ConnectionString был неверно указан путь до базы (когда переносил с ноутбука - забыл поменять).

Теперь я делаю оконное приложение. Смог сделать вывод данных в DataGrid, но не могу понять как сделать показ только тех строк, у которых параметр "urfu" = true.

Подскажите пожалуйста?

C#
1
2
3
4
5
6
7
8
9
10
NewsContext db;
        public Form1()
        {
            InitializeComponent();
 
            db = new NewsContext();
            db.Newes.Load();
 
            dataGridView1.DataSource = db.Newes.Local.ToBindingList();
        }
0
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
05.06.2017, 05:58 11
Scully, как-то так:

C#
1
2
3
using(var con = new NewContext()) {
    dataGridView1.DataSource = con.News.Where(x => x.urfu == true).ToList();
}
Не делайте так:
C#
1
db.Newes.Load();
Зачем вы загружаете содержимое всей таблицы? А если там миллионы записей? Вытаскивайте из БД только то, что нужно и не более того. EF позволяет вам указывать условия для отбора записей на стороне СУБД. Так же EF позволяет указать сколько записей вам нужно.
1
Scully
0 / 0 / 1
Регистрация: 21.05.2014
Сообщений: 26
05.06.2017, 12:25  [ТС] 12
Usaga, спасибо!

А возможно ли как-то делать выборку последних 40 записей? Просто сейчас, чтобы проверить есть ли проверяемая новость в базе, я проверяю все записи (на совпадение по названию записи) при помощи цикла foreach.
0
Usaga
Эксперт .NET
5791 / 4039 / 718
Регистрация: 21.01.2016
Сообщений: 15,800
Завершенные тесты: 2
05.06.2017, 12:27 13
Scully, такая проверка делается одним запросом к БД. Без циклов.
0
Scully
0 / 0 / 1
Регистрация: 21.05.2014
Сообщений: 26
05.06.2017, 14:51  [ТС] 14
Usaga, а какой запрос выделяет "name" у последних 40 строк? И как оформляется запрос к БД средсвами VS и C# (синтаксис)?
0
05.06.2017, 14:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.06.2017, 14:51

Entity Framework, не работает подключение к существующей базе
Здравствуйте! Начал изучать EF по следующим урокам: http://metanit.com/sharp/entityframework/ ...

Как реализовать проверку значения, которое уже ранее было выбрано и сообщить пользователю?
Как реализовать проверку значение, которое уже ранее было выбрано и сообщить пользователю о том,...

Создание поискового запроса к базе данных с использованием Entity Framework
Не могу составить поисковый запрос к базе данных используя Entity Framework. Сложность в том, что...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru