Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何优雅的实现字典管理 #1997

Open
gitlsl opened this issue Mar 12, 2025 · 1 comment
Open

如何优雅的实现字典管理 #1997

gitlsl opened this issue Mar 12, 2025 · 1 comment

Comments

@gitlsl
Copy link

gitlsl commented Mar 12, 2025

现在后台系统都需会有字典管理功能, 其实就一张KV大表, 放了很多值用type做区分,
有没优雅的视实现的方式, 可以映射 不同的类型到这个大表?

Feature 特性

public class Dictionary
{//通用配置表 ,  实际建表
    public string Id{get;set;}
    public string A{get;set;}
    public string B{get;set;}
    public string C{get;set;}
    public string D{get;set;}
    public string Type{get;set;}
}

简要描述原因

[Map(typeof(Dictionary),  where:"type=ConfigA")]
public class ConfigA
{// 类映射到Dictionary ,  不建表,  有点像导航属性
    public string Id{get;set;}
    
    [Map("A")]
    public string A1{get;set;}
      [Map("B")]
    public string B1{get;set;}
      [Map("C")]
    public string C1{get;set;}
}

类似这样, 就把 ConfigA 映射到 Dictionary , 通过type=ConfigA进行过滤, 字段也进行了映射, 可以进行crud, 最终操作还是Dictionary的操作

使用场景

这样就非常方便优雅

// c# code
@2881099
Copy link
Collaborator

2881099 commented Mar 12, 2025

利用 全局过滤器 + Aop 实现如下效果:

[MapTable(typeof(SysParam), nameof(SysParam.Value), "001")]
class Param001
{
    [Column(Name = "Value2")]
    public string Name { get; set; }
    [Column(Name = "Value3")]
    public int Age { get; set; }
}
fsql.Select<Param001>().ToList();
//SELECT Value2, Value3 FROM SysParam WHERE Value = '001'

public class SysParam
{
    public int Id { get; set; }
    public string Value { get; set; }
    public string Value2 { get; set; }
    public string Value3 { get; set; }
    //...
}

//实现关键
fsql.Aop.ConfigEntity += (s, e) =>
{
    var attr = e.EntityType.GetCustomAttribute<MapTableAttribute>();
    if (attr != null)
    {
        var dbname = (fsql.CodeFirst as CodeFirstProvider)._commonUtils.GetEntityTableAttribute(attr.Type).Name;
        var prop = attr.Type.GetProperty(attr.PropertyName);
        var propValue = Utils.GetDataReaderValue(prop.PropertyType, attr.PropertyValue);
        e.ModifyResult.Name = dbname;
        e.ModifyResult.DisableSyncStructure = true;
        var paramExp = Expression.Parameter(e.EntityType);
        var lambdaExp = Expression.Lambda(typeof(Func<,>).MakeGenericType(e.EntityType, typeof(bool)),
            Expression.Equal(Expression.MakeMemberAccess(Expression.TypeAs(paramExp, attr.Type), prop), Expression.Constant(propValue)), paramExp);
        var applyOnly = fsql.GlobalFilter.GetType().GetMethods().Where(a => a.Name == "ApplyOnly").FirstOrDefault();
        applyOnly.MakeGenericMethod(e.EntityType).Invoke(fsql.GlobalFilter, new object[] { $"MapTable_filter_{e.EntityType.FullName}", lambdaExp, false });
    }
};
public class MapTableAttribute : Attribute
{
    public Type Type { get; set; }
    public string PropertyName { get; set; }
    public object PropertyValue { get; set; }

    public MapTableAttribute(Type type = null, string propertyName = null, object propertyValue = null)
    {
        Type = type;
        PropertyName = propertyName;
        PropertyValue = propertyValue;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants