我有一个方法可以根据给定的参数从不同的存储库中检索数据。
private async Task<string> GetByIdFrom(EntityArgs args)
{
string content = null;
switch (args.CollectionName.ToLowerInvariant())
{
case Common.WorkingSite:
var workingsite = await (new Repository<WorkingSite>())
.GetByKeyAsync(args.Id);
if (workingsite != null)
content = workingsite.Content;
break;
case Common.ProductInstruction:
var productInfo = await (new Repository<ProductInstruction>())
.GetByKeyAsync(args.Id);
if (productInfo != null)
content = productInfo.Content;
break;
case Common.Resource:
var resource = await (new Repository<Resource>())
.GetByKeyAsync(args.Id);
if (resource != null)
content = resource.Content;
break;
default:
Logger.Warn("GetById(): Table {0} not found", args.CollectionName);
break;
}
return content;
}
如果switch
有效,您可以看到cases
完全是重复,Content
全部args.Id
返回EntityArgs
。内容总是复杂的JSON。
CollectionName
属性为string
,因为请求来自JavaScript客户端; CollectionName
只是在.NET部分上标识SQLite
表。
Repository<T>
的所有上述类都实现了相同的抽象基础Entity
。
[JsonObject]
public abstract class Entity
{
protected Entity()
{}
[PrimaryKey]
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
[JsonIgnore]
public string Content { get; set; }
}
存储库实现如下,其中SQLiteDataProvider
是SQLite-net
ORM的包装,连接到本地SQLite
数据库。
public class Repository<T> where T : new()
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
/// <summary>
/// Get by primary key
/// </summary>
public virtual async Task<T> GetByKeyAsync(object key)
{
var item = default(T);
try
{
item = await SQLiteDataProvider.Connection.GetAsync<T>(key);
}
catch (Exception e)
{
if ((e is InvalidOperationException) && e.Message.Contains("no elements"))
{
_logger.Info("GetByKeyAsync<{0}> - {1}", (typeof(T)).Name, e.Message);
}
else
{
_logger.Error(e);
throw;
}
}
return item;
}
// ...other methods
}
我非常确定我应该能够摆脱整个switch
语句,只需要调用类似
var item = await (new Repository<Entity>()).GetByKeyAsync(args.Id);
return item != null ? item.Content : null;
...当然上面没有工作,因为我需要知道对应底层数据库表的具体类。
我无法理解它。想法?
答案 0 :(得分:1)
Sicne所有类型都实现Entity
,您可以创建一个通用方法,要求type参数继承它,以便您可以访问Content
属性。
private async Task<string> GetByIdFrom<T>(EntityArgs args)
where T : Entity
{
T entity = await (new Repository<T>()).GetByKeyAsync(args.Id);
if (entity != null)
return entity.Content;
return null;
}
请注意,您仍然需要一个包含交换机的非泛型方法,以便根据args.CollectionName
选择要遵循的路径。但至少它变得更加简洁:
private async Task<string> GetByIdFrom(EntityArgs args)
{
switch (args.CollectionName.ToLowerInvariant())
{
case WorkingSite:
return GetByIdFrom<WorkingSite>(args);
case ProductInstruction:
return GetByIdFrom<ProductInstruction>(args);
case Resource:
return GetByIdFrom<Resource>(args);
default:
Logger.Warn("GetById(): Table {0} not found", args.CollectionName);
break;
}
}