Cấu trúc / kỹ thuật dữ liệu lý tưởng để lưu trữ dữ liệu lịch trình chung trong C #


8

Tôi đang cố gắng thực hiện một đối tượng lập lịch chung trong C # 4 sẽ xuất ra một bảng trong HTML. Mục đích cơ bản là hiển thị một số đối tượng cùng với các thuộc tính khác nhau và liệu nó có đang làm gì đó trong một khoảng thời gian nhất định hay không.

Bộ lập lịch sẽ xuất ra một bảng hiển thị các tiêu đề:

Detail Field 1 ....N| Date1.........N

Tôi muốn khởi tạo bảng với ngày bắt đầu và ngày kết thúc để tạo phạm vi ngày (lý tưởng nhất cũng có thể thực hiện các khoảng thời gian khác, ví dụ như giờ nhưng điều đó không quan trọng). Sau đó tôi muốn cung cấp một đối tượng chung sẽ có các sự kiện liên quan.

Trường hợp một đối tượng có các sự kiện trong khoảng thời gian tôi muốn một ô bảng được đánh dấu

Ví dụ

Name Height Weight 1/1/2011 2/1/2011 3/1/20011...... 31/1/2011
Ben  5.11    75       X        X                       X
Bill 5.7     83                X        X

Vì vậy, tôi đã tạo lịch trình với Ngày bắt đầu = 1/1/2011 và ngày kết thúc 31/1/2011

Tôi muốn cung cấp cho nó đối tượng người của tôi (đã được sắp xếp) và cho nó biết trường nào tôi muốn hiển thị (Tên, Chiều cao, Trọng lượng)

Mỗi người có các sự kiện có ngày bắt đầu và ngày kết thúc. Một số sự kiện sẽ bắt đầu và kết thúc với nhau nhưng chúng vẫn sẽ được hiển thị vào ngày thích hợp, v.v.

Lý tưởng nhất là tôi cũng muốn có thể cung cấp cho nó một đối tượng đặt phòng lớp. Vì vậy, tôi đang cố gắng để giữ cho nó chung chung.

Tôi đã thấy các triển khai Javasript vv tương tự.

Một cấu trúc dữ liệu tốt sẽ là gì cho điều này? Bất kỳ suy nghĩ về các kỹ thuật tôi có thể sử dụng để làm cho nó chung chung. Tôi không tuyệt vời với thuốc generic nên bất kỳ lời khuyên nào cũng được đánh giá cao.


với generic bạn vẫn cần một lớp cơ sở hoặc giao diện để làm cho nó an toàn. Bạn có thể sử dụng Reflection để lấy Thuộc tính khi chạy, nhưng tốc độ này chậm hơn và chỉ ném trong thời gian chạy
Firo

Vâng, tôi đã mong đợi lớp cơ sở của cấu trúc dữ liệu sẽ có một số loại cấu trúc giữ các tiêu đề cột bên (có thể là 1 ... đến n), một số loại cấu trúc giữ các tiêu đề cột chính (sẽ lớn như thời gian dấu chấm), và sau đó các cấu trúc giữ các hàng thực tế. Phần chung là khả năng vượt qua một số đối tượng ngẫu nhiên và xác định cái mà sau đó tôi sẽ xác định các cột tôi cần cho v.v.
GraemeMiller

Bạn đã bao giờ nghĩ đến việc sử dụng từ khóa "động" cho nhiệm vụ này chưa?
Dimi Takis

1
Cuộc thảo luận thú vị này về thiết kế xung quanh dữ liệu có thể mang lại cho bạn định hướng / cảm hứng.
TheSilverBONS

Nếu bạn không cần thực hiện bất kỳ thao tác thực tế nào trên dữ liệu trường (chiều cao, cân nặng, v.v.), bạn có thể sử dụng phản xạ như được nêu trong câu trả lời này trên Stack Overflow để lấy các giá trị và tên thuộc tính hiển thị từ đối tượng.
nemec

Câu trả lời:


2

Tôi không nghĩ rằng điều này là quá khó khăn. Tôi đang thiếu gì?

using System;
using System.Collections.Generic;

public class ScheduledPerson {
    public string Name {get; set;}

    public Dictionary<string, Object> Fields {
        get { return _fields; }
        set { _fields = value; }
    }
    private Dictionary<string, Object> _fields = new Dictionary<string, Object>();

    public List<Tuple<DateTime, DateTime>> Events {
        get { return _events; }
        set { _events = value; }
    }
    private List<Tuple<DateTime, DateTime>> _events = new List<Tuple<DateTime, DateTime>>();

    public ScheduledPerson(string name){
        Name = name;
    }
}

Tôi không thấy một cách hay để làm cho các lớp lên lịch của chúng ta chung chung, vì dường như các trường có thể là bất cứ thứ gì. Tôi đang lưu trữ các giá trị trường dưới dạng Đối tượng, vì tôi thấy không có gì đòi hỏi chúng phải là động lực học. Chỉ cần đảm bảo tất cả các loại giá trị trường có triển khai ToString () hợp lý.

Nếu bạn muốn Sự kiện là Danh sách DateRange hoặc của lớp Sự kiện của riêng bạn thay vì Tuple, hãy thoải mái.

Sau đó, bạn vẫn có thể viết một lớp riêng biệt để hiển thị mỗi Trình lập lịch biểu trong một bảng, cùng với việc tìm ra tất cả các tiêu đề từ tất cả các bản ghi của Lịch trình. Nếu bạn đang giao dịch với mười nghìn người, bạn sẽ muốn một giải pháp tốt hơn có tất cả các tiêu đề được lưu trữ, nhưng đối với hầu hết các ứng dụng, sẽ không quá tệ khi liệt kê tất cả các Trường trên tất cả các Lịch biểu để tìm ra các tiêu đề.


0

Nói chung, tôi sẽ không lưu trữ dữ liệu cho giải pháp của bạn dựa trên cách bạn muốn hiển thị nó. Điều đó dẫn đến các giải pháp rất cụ thể sẽ gây khó khăn khi nhu cầu của bạn thay đổi. Tôi sẽ chia nhỏ mọi thứ về các thực thể trong giải pháp của bạn và sau đó tạo một nhóm Truy vấn LINQ sẽ tạo dữ liệu hiển thị của bạn khi đến lúc tạo báo cáo.

Tất cả các mã dưới đây là cấu trúc và bỏ qua khởi tạo, vv

public class Person
{
   public string Name {get;set;}
   public double Height {get;set;}
   public double Weight {get;set;}
}

public class ScheduledEvent
{
   public Person Attendee {get;set;}
   public DateTime EventDate {get;set;}
}

public class Schedule
{
   public DateTime StartDate {get;set; }
   public DateTIme EndDate {get;set;}
   List<Person> Persons {get;set;}
   List<ScheduledEvent> SheduledEvents {get;set;}
}

Bây giờ, trong thực tế, tôi sẽ lưu trữ chúng trong một cơ sở dữ liệu thuộc loại nào đó và thực hiện tất cả các truy vấn trong thời gian chạy với một cái gì đó như NHibernate hoặc Entity Framework. Nhưng đối với mục đích demo trong bộ nhớ, các truy vấn để tạo các dòng bảng của bạn sẽ như sau:

class TableRow
{
   string Name { get;set; }
   string Height {get;set; }
   string Weight {get;set; }
   List<string> DatesWithEvents {get; }
}

var columns = List<string>{ "Name", "Height", "Weight", }.Concat(
                schedule.ScheduledEvents
                  .Select(e=> e.EventDate.ToShortDate())
                  .Distinct())
              .ToList();
var rows = new List<TableRow>();

foreach(var p in schedule.Persons) 
{
   var row = new TableRow();
   row.Name = p.Name;
   row.Height = p.Height;
   row.Weight = p.Weight;
   row.DatesWithEvents = schedule.ScheduledEvents
     .Where(e => e.Person == p)
     .Select(e => e.EventDate.ToShortDate()).Distinct().ToList();
   rows.Add(row);
}    

Sau đó, trong trình kết xuất của bạn, chỉ cần ghép các cột để biết vị trí dán 'X' để đánh dấu ngày được điền. Với nhiều nỗ lực hơn, bạn có thể tái cấu trúc nó thành một giải pháp thanh lịch hơn nhiều, nhưng đây là điều cơ bản.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.