#c# #asp.net #entity-framework
#c# #asp.net #entity-framework
Вопрос:
В рамках проекта, над которым я работаю, пользователи могут создать публикацию, а затем другие пользователи смогут нажать на кнопку «нравится» или «не нравится».
Приведенный ниже код представляет собой класс Post.cs, отвечающий за добавление таблиц в базу данных.
public class Post
{
//The post ID
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int postId { get; set; }
// Foreign key to customer
public string Id { get; set; }
public string Email { get; set; }
public string postTitle { get; set; }
public string postBody { get; set; }
public string postDepartment { get; set; }
public string postCategory { get; set; }
public bool postAnonymous { get; set; }
public int postLikes { get; set; }
public int postDislikes { get; set; }
public DateTime postDate { get; set; }
}
Следующий код является внутренним кодом C #, который связан с любой из кнопок.
protected void btnLike_Click(object sender, EventArgs e)
{
}
protected void btnDislike_Click(object sender, EventArgs e)
{
}
Я пытаюсь заставить кнопки увеличивать целочисленное значение в базе данных на 1 за каждый клик, и пользователи должны иметь возможность нажимать только на одно из них, не имея возможности ставить лайк / не нравится более одного раза.
Как бы я попытался сделать это успешно, используя asp.net веб-формы.
<—————— РЕДАКТИРОВАТЬ————————->
protected void btnLike_Click(object sender, EventArgs e)
{
var postIDforLike = // add logic to get the id of the post to increment the likes
using (var _dbContext = new ApplicationDbContext())
{
var addLikeSql = "update post set postLikes = postLikes 1 where postID = @id";
var paramID = new SqlParameter("@id", postIDforLike);
_dbContext.Database.ExecuteSqlCommand(addLikeSql, paramID);
}
}
<————————— ПРАВКА2————————>
<asp:Button ID="btnLike" class="btn btn-primary" runat="server" Text="👍 Like" Width="99.99px" OnClick="btnLike_Click" />amp;nbsp <asp:Button ID="btnDislike" Width="99.99px" class="btn btn-primary" runat="server" Text="Dislike 👎" OnClick="btnDislike_Click" />
</div>
<br />
<%--------------------------------------
Inserting Comment Information
--------------------------------------%>
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title text-center">Add Comment</h3>
</div>
<div class="panel-body">
<fieldset>
<table class="nav-justified">
<tr>
<td class="modal-sm" style="width: 237px; height: 21px;">
<label for="commentBody" class="col-lg-2 control-label">Comment:</label></td>
<td style="width: 434px; height: 21px;">
<asp:TextBox Width="400px" style="resize:none;" class="form-control" ID="commentBody" runat="server" placeholder="Body" TextMode="MultiLine"></asp:TextBox>
</td>
<td style="height: 21px">
<asp:RequiredFieldValidator controltovalidate="commentBody" ID="commentBodyValidator" runat="server" ErrorMessage="*Comment is required" ForeColor="Red"></asp:RequiredFieldValidator>
</td>
</tr>
</table>
<br />
<table class="nav-justified">
<tr>
<td style="height: 21px; width: 511px">
<label for="commentAnonymous" class="col-lg-2 control-label" style="left: 0px; top: 0px; width: 538px">Would you like this comment to be submitted anonymously?:</label></td>
<td style="height: 21px; width: 104px">
<asp:RadioButtonList ID="commentAnonymous" runat="server" BorderStyle="None" CellPadding="0" CellSpacing="0">
<asp:ListItem Value="1" Text="Yes">Yes</asp:ListItem>
<asp:ListItem Value="0" Text="No">No</asp:ListItem>
</asp:RadioButtonList>
</td>
<td style="height: 21px"><asp:RequiredFieldValidator controltovalidate="commentAnonymous" ID="commentAnonymousValidator" runat="server" ErrorMessage="*Please select an option" ForeColor="Red"></asp:RequiredFieldValidator>
</td>
</tr>
</table>
<br />
<table class="nav-justified">
<tr>
<td class="modal-sm" style="width: 408px">amp;nbsp;</td>
<td>
<button type="reset" class="btn btn-default">Cancel</button>
<asp:Button class="btn btn-default" ID="commentSubmitBtn" runat="server" autopostback="false" onclick="AddComment" Text="Submit" />
</td>
<td>amp;nbsp;</td>
</tr>
</table>
</fieldset>
<hr>
<table class="display" id="commentsTable">
<thead>
<tr>
<th>Comment</th>
<th>User</th>
<th>Date</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Ответ №1:
Я предполагаю, что вы используете Entity Framework (на основе атрибутов, используемых в классе post).
Самый простой способ сделать это — загрузить объект, увеличить значение и затем вызвать SaveChanges. Но это очень неэффективно, а также опасно, если вы не используете механизм блокировки.
То, что вы, вероятно, ищете, это
update post set postLikes = postLikes 1 where postID = @id
команда. Это уже было бы более эффективно, потому что вы не загружаете весь пост каждый раз перед обновлением значения «Нравится». Вы можете выполнять Sql-команды, подобные этой, используя Database.Выполните команду SQL из вашего контекста.
Другим возможным решением было бы изменить вашу модель БД, добавив таблицу «Нравится» и «Не нравится», куда вы добавляете запись для каждого «нравится» / «не нравится». Чтобы получить текущее количество лайков, вы должны посчитать количество записей, связанных с публикацией. Это увеличивает накладные расходы, но имеет то преимущество, что вы не создаете узкое место, потому что базе данных приходится блокировать вашу запись post каждый раз, когда вы хотите обновить поле like.
Комментарии:
1. да, я использую Entity Framework, приношу извинения за то, что не указал этого в моем первоначальном вопросе. Я бы, вероятно, предпочел сохранить его в таблице posts вместо создания новой таблицы, поскольку это имело бы для меня больше смысла. Но я не понимаю, почему я бы поместил инструкцию update post, которую вы предложили? хотя для меня это имеет смысл
2. Вы можете найти объяснение, как выполнить инструкцию sql здесь: learnentityframeworkcore.com/raw-sql#database.executesqlcommand
3. Я просмотрел этот пример, там есть только 1 строка, которую я не получаю, и это » var name = new SqlParameter («@CategoryName», «Test»); » один. Я отредактировал свой вопрос с помощью нового кода, который я добавил, не могли бы вы проверить, правильно ли он выглядит?
4. Я изменил вашу правку, чтобы исправить строку, с которой у вас возникли проблемы. Новый SqlParameter необходим для установки значения параметра Value для параметра @id в Sql.
5. Идеально! Это устранило проблему с проверкой, и весь остальной код верен! 😀 Лайки и антипатии работают должным образом : D Большое вам спасибо за ответы на все мои вопросы для новичков и откровенность со мной 🙂
Ответ №2:
// У вас должна быть новая таблица, которая обрабатывает таблицу user-post-like / / UserLike, которая имеет userId int postID int Нравится или не нравится, поэтому вам не нужны атрибуты Likes и Dislikes для entity! // Предположим, что эта операция может быть выполнена пользователем, вошедшим в систему.
protected void btnLike_Click(object sender, EventArgs e)
{
//you need to get postId while button clicked...
DBContext db = new DbContext();
var user = Session["loggedUser"] as User ;
var didUserLike = db.Post.Where(p=>p.PostId == postId).Select(x=>x.UserId == user.UserId).FirstOrDefault());
if(didUserLike.Count() > 0){
//Operation like enable button disable button!
} //and if you want to do it for dislike..yes you can
}
Извините, у меня здесь нет studio или code, я не могу это контролировать.Но я думаю, вы понимаете структуру. Хорошего дня.
Отредактировано (добавлено):
и в представлении вам не нужно показывать из атрибута вашего enetiyt, потому что это может быть вычислено с помощью запроса. Это неправильно для проектирования базы данных.
и вы можете сделать это следующим образом ;
public int likeCountForPost(int id){
var postLikes = db.PostLikes.Where(x=>x.PostId == id amp;amp; x.PostLike==1).Count();
return postLikes;
}
Вы также можете сделать это, изменив всего 1 на 2 для возвращаемого количества отклонений.