我想将数据库表定义为C#Sharp中的类。我现在的操作方式似乎很复杂,我认为我做错了。
当前,我像这样在定义public static class
中定义列名:
public const string ID = "image_id";
public const string NAME = "image_name";
public const string PATH = "image_path";
public const string DESCRIPTION = "image_description";
public const string THUMBNAIL = "image_thumbnail";
public const string RATING = "image_rating";
public const string VIEW_COUNT = "image_view_count";
public const string WATCH_TIME_SECONDS = "image_watch_time_seconds";
public const string SIZE_BYTES = "image_size_bytes";
public const string WIDTH = "image_width";
public const string HEIGHT = "image_height";
public const string MEGAPIXEL = "image_megapixel";
public const string FFPROBE_SCORE = "image_ffprobe_score";
public const string IS_FAV = "image_is_fav";
public const string DATE_FAV = "image_date_fav";
public const string DATE_CREATED_AT = "image_date_created_at";
public const string DATE_ADDED_TO_DB = "image_date_added_to_db_at";
public const string DATE_UPDATED_AT = "image_date_updated_at";
public const string DATE_LAST_LOOKUP_AT = "image_date_last_lookup_at";
然后我有一个字典,将每个列与一种类型相关联:
public static readonly Dictionary<string, string> TypesDictionary =
new Dictionary<string, string>()
{
{ID, DbDataTypes.DB_DATATYPE_INTEGER},
{NAME, DbDataTypes.DB_DATATYPE_TEXT},
{PATH, DbDataTypes.DB_DATATYPE_TEXT},
{DESCRIPTION, DbDataTypes.DB_DATATYPE_TEXT},
{THUMBNAIL, DbDataTypes.DB_DATATYPE_TEXT},
{RATING, DbDataTypes.DB_DATATYPE_INTEGER},
{VIEW_COUNT, DbDataTypes.DB_DATATYPE_INTEGER},
{WATCH_TIME_SECONDS, DbDataTypes.DB_DATATYPE_INTEGER},
{SIZE_BYTES, DbDataTypes.DB_DATATYPE_INTEGER},
{WIDTH, DbDataTypes.DB_DATATYPE_INTEGER},
{HEIGHT, DbDataTypes.DB_DATATYPE_INTEGER},
{MEGAPIXEL, DbDataTypes.DB_DATATYPE_INTEGER},
{FFPROBE_SCORE, DbDataTypes.DB_DATATYPE_INTEGER},
{IS_FAV, DbDataTypes.DB_DATATYPE_BOOLEAN},
{DATE_FAV, DbDataTypes.DB_DATATYPE_DATETIME},
{DATE_LAST_LOOKUP_AT, DbDataTypes.DB_DATATYPE_DATETIME},
{DATE_ADDED_TO_DB, DbDataTypes.DB_DATATYPE_DATETIME},
{DATE_CREATED_AT, DbDataTypes.DB_DATATYPE_DATETIME},
{DATE_UPDATED_AT, DbDataTypes.DB_DATATYPE_DATETIME}
};
然后我还有另一本字典,它为某些列定义了默认值:
public static readonly Dictionary<string, string> DefaultsDictionary =
new Dictionary<string, string>()
{
{RATING, "0"},
{VIEW_COUNT, "0"},
{WATCH_TIME_SECONDS, "0"},
{SIZE_BYTES, "-1"},
{WIDTH, "-1"},
{HEIGHT, "-1"},
{MEGAPIXEL, "-1"},
{FFPROBE_SCORE, "-1"},
{IS_FAV, "0"},
{DATE_ADDED_TO_DB, "(DATETIME('now'))"},
{DATE_UPDATED_AT, "CURRENT_TIMESTAMP"},
};
然后,我使用另一个字典来定义特殊列属性,例如PRIMARY KEY
,UNIQUE
等:
public static readonly Dictionary<string, string> SpecialDictionary =
new Dictionary<string, string>()
{
{ID, "PRIMARY KEY"},
{PATH, "NOT NULL UNIQUE"},
{DATE_ADDED_TO_DB, "NOT NULL"},
{DATE_UPDATED_AT, "NOT NULL"},
};
然后,我将所有这些字典放入另一个字典中:
public static readonly Dictionary<string, Dictionary<string, string>> DefinesDictionary =
new Dictionary<string, Dictionary<string, string>>()
{
{DbDataTypes.DB_DATA_TYPES, TypesDictionary},
{DbDataTypes.DB_DEFAULTS, DefaultsDictionary},
{DbDataTypes.DB_SPECIAL, SpecialDictionary}
};
[我把这个^^字典放在代表所有表格的字典中。 (并且每个表都为每个表定义了以上字典:
public static readonly Dictionary<TableName, Dictionary<string, Dictionary<string, string>>> TablesDictionary =
new Dictionary<TableName, Dictionary<string, Dictionary<string, string>>>()
{
{TableName.PersonTable, PersonTableDefinitions.DefinesDictionary},
{TableName.ImageTable, ImageTableDefinitions.DefinesDictionary},
{TableName.TagTable, TagTableDefinitions.DefinesDictionary},
{TableName.TagAliasTable, TagAliasDefinitions.DefinesDictionary},
{TableName.PersonImageTable, PersonImageTableDefinitions.DefinesDictionary},
{TableName.TagImageTable, TagImageDefinitions.DefinesDictionary},
};
这样,我可以在查询数据库或创建表时访问所有数据库定义。每当我在数据库中添加或删除列或更改默认值或约束时,都无需更改代码中的任何其他内容。但这感觉非常令人费解。另外,我一直在使用<string,string>
字典来存储数据库值(查询结果),例如,当我执行SELECT * FROM Image
时,我会将结果解析为List<string,string>
。这非常不安全且容易出错,因为没有任何内容这样可以确保我当前正在处理的列表实际上与我认为与之对应的模型相对应。因此,我想将每个表解析为一个单独的模型类。但这使问题更加复杂。例如,对于图像类,我做了一个枚举,表示像这样的列名:
public enum ImageColumnName
{
Id,
Name,
Path,
Description,
Thumbnail,
Rating,
ViewCount,
WatchTimeSeconds,
SizeBytes,
Width,
Height,
Megapixel,
FfprobeScore,
IsFav,
DateFav,
DateCreatedAt,
DateAddedToDb,
DateUpdatedAt,
DateLastLookupAt
}
然后我制作了2个将枚举转换为列名的字典,反之亦然:
public static readonly Dictionary<ImageColumnName, string> ImageColumnNameEnumToString =
new Dictionary<ImageColumnName, string>
{
{ImageColumnName.Id, ID},
{ImageColumnName.Name, NAME},
{ImageColumnName.Path, PATH},
{ImageColumnName.Description, DESCRIPTION},
{ImageColumnName.Thumbnail, THUMBNAIL},
{ImageColumnName.Rating, RATING},
{ImageColumnName.ViewCount, VIEW_COUNT},
{ImageColumnName.WatchTimeSeconds, WATCH_TIME_SECONDS},
{ImageColumnName.SizeBytes, SIZE_BYTES},
{ImageColumnName.Width, WIDTH},
{ImageColumnName.Height, HEIGHT},
{ImageColumnName.Megapixel, MEGAPIXEL},
{ImageColumnName.FfprobeScore, FFPROBE_SCORE},
{ImageColumnName.IsFav, IS_FAV},
{ImageColumnName.DateFav, DATE_FAV},
{ImageColumnName.DateCreatedAt, DATE_CREATED_AT},
{ImageColumnName.DateAddedToDb, DATE_ADDED_TO_DB},
{ImageColumnName.DateUpdatedAt, DATE_UPDATED_AT},
{ImageColumnName.DateLastLookupAt, DATE_LAST_LOOKUP_AT}
};
public static readonly Dictionary<string, ImageColumnName> ImageColumnNameStringToEnum =
new Dictionary<string, ImageColumnName>
{
{ID,ImageColumnName.Id},
{NAME,ImageColumnName.Name},
{PATH,ImageColumnName.Path},
{DESCRIPTION,ImageColumnName.Description},
{THUMBNAIL,ImageColumnName.Thumbnail},
{RATING,ImageColumnName.Rating},
{VIEW_COUNT,ImageColumnName.ViewCount},
{WATCH_TIME_SECONDS,ImageColumnName.WatchTimeSeconds},
{SIZE_BYTES,ImageColumnName.SizeBytes},
{WIDTH,ImageColumnName.Width},
{HEIGHT,ImageColumnName.Height},
{MEGAPIXEL,ImageColumnName.Megapixel},
{FFPROBE_SCORE,ImageColumnName.FfprobeScore},
{IS_FAV,ImageColumnName.IsFav},
{DATE_FAV,ImageColumnName.DateFav},
{DATE_CREATED_AT,ImageColumnName.DateCreatedAt},
{DATE_ADDED_TO_DB,ImageColumnName.DateAddedToDb},
{DATE_UPDATED_AT,ImageColumnName.DateUpdatedAt},
{DATE_LAST_LOOKUP_AT,ImageColumnName.DateLastLookupAt}
};
然后我定义一个ImageModel
类,在那里我将所有列定义为成员变量:
public class ImageModel : BaseModel
{
#region Db Columns
private int _id;
private string _name;
private string _path;
private string _description;
private string _thumbnail;
private int _rating;
private int _viewCount;
private int _watchTimeSeconds;
private int _sizeBytes;
private int _width;
private int _height;
private int _megapixel;
private int _ffprobeScore;
private int _isFav;
private DateTime _dateFav;
private DateTime _dateCreatedAt;
private DateTime _dateAddedToDb;
private DateTime _dateUpdatedAt;
private DateTime _dateLastLookupAt;
#endregion
}
然后我为每个属性定义属性:
#region Properties
public DateTime DateLastLookupAt
{
get => _dateLastLookupAt;
set => ChangeValue(value, ImageColumnName.DateLastLookupAt);
}
public DateTime DateUpdatedAt
{
get => _dateUpdatedAt;
set => ChangeValue(value, ImageColumnName.DateUpdatedAt);
}
public DateTime DateAddedToDb
{
get => _dateAddedToDb;
set => ChangeValue(value, ImageColumnName.DateAddedToDb);
}
public DateTime DateCreatedAt
{
get => _dateCreatedAt;
set => ChangeValue(value, ImageColumnName.DateCreatedAt);
}
public DateTime DateFav
{
get => _dateFav;
set => ChangeValue(value, ImageColumnName.DateFav);
}
public int IsFav
{
get => _isFav;
set => ChangeValue(value, ImageColumnName.IsFav);
}
public int FfprobeScore
{
get => _ffprobeScore;
set => ChangeValue(value, ImageColumnName.FfprobeScore);
}
public int Megapixel
{
get => _megapixel;
set => ChangeValue(value, ImageColumnName.Megapixel);
}
public int Height
{
get => _height;
set => ChangeValue(value, ImageColumnName.Height);
}
public int Width
{
get => _width;
set => ChangeValue(value, ImageColumnName.Width);
}
public int SizeBytes
{
get => _sizeBytes;
set => ChangeValue(value, ImageColumnName.SizeBytes);
}
public int WatchTimeSeconds
{
get => _watchTimeSeconds;
set => ChangeValue(value, ImageColumnName.WatchTimeSeconds);
}
public int ViewCount
{
get => _viewCount;
set => ChangeValue(value, ImageColumnName.ViewCount);
}
public int Rating
{
get => _rating;
set => ChangeValue(value, ImageColumnName.Rating);
}
public string Thumbnail
{
get => _thumbnail;
set => ChangeValue(value, ImageColumnName.Thumbnail);
}
public string Description
{
get => _description;
set => ChangeValue(value, ImageColumnName.Description);
}
public string Path
{
get => _path;
set => ChangeValue(value, ImageColumnName.Path);
}
public string Name
{
get => _name;
set => ChangeValue(value,ImageColumnName.Name);
}
public int Id
{
get => _id;
}
#endregion
ChangeVlaue
函数跟踪更改的列。因此,当我想更新数据库条目时,我只会更新已更改的列。
这令人费解。而且我肯定做错了。我真的很高兴听到我的方法在哪里做错了。
我为冗长的帖子表示歉意,我想包括所有相关代码,因此很明显为什么我认为这很复杂。因此,最重要的是我如何将数据库表和行定义为C#对象?
您可以将Data Annotations与Entity Framework结合使用来定义模型类。
模型将如下所示:
[Table("your_table")]
public class Entity
{
[Column("your_column")]
public string Value {get; set;}
}
这将为“ your_table”创建一个模型,并读取“ your_column”列。您还可以在名称空间中使用其他属性定义主键或外键值。