【问题标题】:How to transform string to entity object?如何将字符串转换为实体对象?
【发布时间】:2019-09-26 16:19:15
【问题描述】:

我需要从字符串中动态获取实体对象值。 像这样:

string s = "UserMaster";
string param = "MyUser";
object o = database.s.Find(param);
//I need o to become like object o = db.UserMaster.Find(MyUser);

抱歉,如果已经有执行此操作的功能,我不知道名称。 谢谢你的指导:)

编辑: 好的,这是更大的图景:

string myString = "Hi my name is [UserMaster.Name] and my school is [SchoolMaster.SchoolName]";

假设我得到了字符串“[UserMaster.Name]”和“[SchoolMaster.SchoolName]”, UserMaster 和 SchoolMaster 是一个实体名称。 UserMaster 具有“Name”属性,SchoolMaster 具有“SchoolName”属性。 我需要将“[UserMaster.Name]”转换为它的值,比如说“MyName” 和“SchoolMaster.SchoolName”到“MySchoolName”。

【问题讨论】:

  • Find()方法通过主键查找对象,所以如果param是key,就可以使用
  • 这对我来说听起来像是一个 XY 问题。假设你得到这个工作并且你的对象o包含s指定的任何类型,你打算如何使用它?
  • 问题是 DataEntity 不包含 's' 的定义,因为 's' 是字符串而不是实体对象。
  • 这会有什么用?给我们一个大图景,你想通过传递字符串值做什么?

标签: c# entity-framework-6


【解决方案1】:

您可以使用表达式来动态创建代码:

static object DynamicallyGet(string name, params object[] key) {

    var entityName = Expression.Parameter(typeof(string), "entityName");
    var keyValue = Expression.Parameter(typeof(object[]), "keyValue");
    var db = Expression.Variable(typeof(RainDB), "database");
    IList<Expression> procedures = new List<Expression>();

    procedures.Add(Expression.Assign(db, Expression.New(typeof(RainDB))));

    var entityType = typeof(RainDB).GetProperty(name);
    var callMethod = Expression.Call(Expression.MakeMemberAccess(db, entityType), entityType.PropertyType.GetMethod("Find"), keyValue);

    procedures.Add(callMethod);

    var body = Expression.Block(new[] { db }, procedures);
    var lambda = Expression.Lambda<Func<string, object[], object>>(body, entityName, keyValue).Compile();

    return lambda(name , key);



//Call Function:

DynamicallyGet("UserMaster","MyUser")

【讨论】:

    【解决方案2】:

    动态地,当您将 DbSet 作为字符串时(您的情况):

    DbSet mySet = context.Set(Type.GetType("<Your Entity Name>"));
    

    来源: https://entityframeworkcore.com/knowledge-base/33940507/find-a-generic-dbset-in-a-dbcontext-dynamically

    除此之外,动态构建包含参数的字符串是常见的做法。

    通常通过在字符串中使用大括号来实现,例如:

    这是在数据库列中: “您好,我的名字是 {User.FirstName},我来自 {User.Country}”

    这些通常是预定义的值,您可以在代码中替换它们,因为您期望它们。

    然后你做:

    var userId = ...get this from session or from whatever you have in your context.
    var dbUser = db.User.FirstOrDefault(x => x.UserId == userId);
    
    var template = db.Templates.FirstOrDefault(x => x.TemplateName = "userTemplate");
    
    // template is the Db table and TemplateValue is the column
    var text = template.TemplateValue;
    
    text = text.Replace("{User.FirstName}", dbUser.Firstname);
    text = text.Replace("{User.Country}", dbUser.Country);
    

    这可行,但您必须事先知道参数(它们应该是预定义的)。 如果您不知道应该发送什么参数(至少发送者应该知道这些参数以 DB 表/列的形式存在),那么是的,这更棘手,您应该采用我们建议的动态方法。

    祝你好运!

    【讨论】:

    • 不,问题是能够动态指定我认为从哪个 DbSet 读取。
    • 啊,好的,所以他需要在 linq 中对实体进行一些类似的反射
    猜你喜欢
    • 1970-01-01
    • 2013-01-01
    • 2021-02-03
    • 2018-07-19
    • 1970-01-01
    • 2019-07-07
    • 1970-01-01
    相关资源
    最近更新 更多