Tôi đang làm việc trên một ứng dụng mà bạn có thể đăng ký nhận bản tin và chọn danh mục bạn muốn đăng ký. Có hai nhóm danh mục khác nhau: thành phố và danh mục.Tối ưu hóa một thuật toán và/hoặc cấu trúc trong C#
Khi gửi email (là một thị hiếu theo lịch biểu), tôi phải xem thành phố nào và danh mục nào mà người đăng ký đã đăng ký trước khi gửi email. Tức là, nếu tôi đã đăng ký "London" và "Manchester" làm thành phố được lựa chọn và đã chọn "Thực phẩm", "Vải" và "Điện tử" làm danh mục của tôi, tôi sẽ chỉ nhận được các bản tin liên quan đến chúng.
Cấu trúc như sau:
Trên mỗi newsitem trong Umbraco CMS có một chuỗi commaseparated của các thành phố và các loại (có hiệu quả, đây là những lưu trữ như id nút từ các thành phố và loại là các nút trong Umbraco là tốt) Khi tôi đăng ký một hoặc nhiều thành phố và một hoặc nhiều danh mục, tôi lưu trữ các nút thành phố và danh mục trong cơ sở dữ liệu trong các bảng tùy chỉnh. bản đồ quan hệ của tôi trông như thế này:
Và toàn bộ cấu trúc trông như thế này:
Đối với tôi, điều này có vẻ như hai bộ 1-1 .. * quan hệ (một người đăng ký một hoặc nhiều thành phố và một người đăng ký một hoặc nhiều danh mục)
Để tìm email nào gửi người đăng ký, mã của tôi trông giống như sau:
private bool shouldBeAdded = false;
// Dictionary containing the subscribers e-mail address and a list of news nodes which should be sent
Dictionary<string, List<Node>> result = new Dictionary<string, List<Node>>();
foreach(var subscriber in subscribers)
{
// List of Umbraco CMS nodes to store which nodes the html should come from
List<Node> nodesToSend = new List<Node> nodesToSend();
// Loop through the news
foreach(var newsItem in news)
{
// The news item has a comma-separated string of related cities
foreach (string cityNodeId in newsItem.GetProperty("cities").Value.Split(','))
{
// Check if the subscriber has subscribed to the city
if(subscriber.CityNodeIds.Contains(Convert.ToInt32(cityNodeId)))
{
shouldBeAdded = true;
}
}
// The news item has a comma-separated string of related categories
foreach (string categoryNodeId in newsItem.GetProperty("categories").Value.Split(','))
{
// Check if the subscriber has subscribed to the category
if(subscriber.CategoryNodeIds.Contains(Convert.ToInt32(categoryNodeId)))
{
shouldBeAdded = true;
}
}
}
// Store in list
if (shouldBeAdded)
{
nodesToSend.Add(newsItem);
}
// Add it to the dictionary
if (nodesToSend.Count > 0)
{
result.Add(subscriber.Email, nodesToSend);
}
}
// Ensure that we process the request only if there are any subscribers to send mails to
if (result.Count > 0)
{
foreach (var res in result)
{
// Finally, create/merge the markup for the newsletter and send it as an email.
}
}
Trong khi công việc này, tôi hơi lo ngại về hiệu suất khi đạt được số lượng người đăng ký nhất định kể từ khi chúng tôi tham gia ba vòng lặp forested lồng nhau. Ngoài ra, hãy nhớ rằng các giáo viên cũ của tôi rao giảng: "cho mỗi vòng lặp có một cấu trúc tốt hơn"
Vì vậy, tôi muốn phản đối của bạn về giải pháp trên, có điều gì có thể được cải thiện ở đây không? Và nó sẽ gây ra vấn đề hiệu suất theo thời gian?
Bất kỳ trợ giúp/gợi ý nào được đánh giá cao! :-)
Xin cảm ơn trước.
Giải pháp
Vì vậy, sau một vài giờ tốt gỡ lỗi và fumblin' xung quanh cuối cùng tôi đã đưa ra một cái gì đó mà làm việc (ban đầu, nó trông như mã ban đầu của tôi làm việc, nhưng nó đã không)
Đáng buồn thay, tôi không thể có được nó để làm việc với bất kỳ truy vấn LINQ tôi đã cố gắng, vì vậy tôi quay trở lại "ol 'trường phái' cách lặp ;-) thuật toán cuối cùng trông như thế này:
private bool shouldBeAdded = false;
// Dictionary containing the subscribers e-mail address and a list of news nodes which should be sent
Dictionary<string, List<Node>> result = new Dictionary<string, List<Node>>();
foreach(var subscriber in subscribers)
{
// List of Umbraco CMS nodes to store which nodes the html should come from
List<Node> nodesToSend = new List<Node> nodesToSend();
// Loop through the news
foreach(var newsItem in news)
{
foreach (string cityNodeId in newsItem.GetProperty("cities").Value.Split(','))
{
// Check if the subscriber has subscribed to the city
if (subscriber.CityNodeIds.Contains(Convert.ToInt32(cityNodeId)))
{
// If a city matches, we have a base case
nodesToSend.Add(newsItem);
}
}
foreach (string categoryNodeId in newsItem.GetProperty("categories").Value.Split(','))
{
// Check if the subscriber has subscribed to the category
if (subscriber.CategoryNodeIds.Contains(Convert.ToInt32(categoryNodeId)))
{
shouldBeAdded = true;
// News item matched and will be sent. Stop the loop.
break;
}
else
{
shouldBeAdded = false;
}
}
if (!shouldBeAdded)
{
// The news item did not match both a city and a category and should not be sent
nodesToSend.Remove(newsItem);
}
}
if (nodesToSend.Count > 0)
{
result.Add(subscriber.Email, nodesToSend);
}
}
// Ensure that we process the request only if there are any subscribers to send mails to
if (result.Count > 0)
{
foreach (var res in result)
{
// StringBuilder to build markup for newsletter
StringBuilder sb = new StringBuilder();
// Build markup
foreach (var newsItem in res.Value)
{
// build the markup here
}
// Email logic here
}
}
Tôi phải nói rằng tôi không biết gì về Umbraco nhưng tôi đã đánh dấu câu hỏi này vì đó là mô hình * về cách đặt câu hỏi như vậy. – deadlyvices
Cảm ơn deadlyvices :) Tôi biết rằng ví dụ mã trên có thể (và sẽ!) Được refactored đến nhiều hơn một phương pháp. – bomortensen