皇宫的实体变化的实体在运行时

0

的问题

我有一个问题。 我有一个代码的第具有200多个课程,代表所有表格中的数据库。 所有的表格遵循同样的格式。 它是能够动态地变化的码在运行时在以下方式?

var coffeeList = new ObservableCollection<GenericCoffeeList>();
var query = (from c in ctxCoin.Coffee1
             select new GenericCoffeeList { CoffeeCatalogId = c.Id, Name = c.Name, Type = c.Type })
             .ToList();

foreach (var c in query)
{
    coinList.Add(c);
}

这里是下一个实体的类型几乎是一样的。 唯一的变化是实体

var coffeeList = new ObservableCollection<GenericCoffeeList>();

var query = (from c in ctxCoin.Coffee2
             select new GenericCoffeeList { CoffeeCatalogId = c.Id, Name = c.Name, Type = c.Type })
             .ToList();

foreach (var c in query)
{
    coinList.Add(c);
}

有没有办法改变的实体在运行时或者我会得到代码中的每一个实体? 谢谢你的任何方向上的这个问题。

c# dbcontext dynamic entity
2021-11-17 02:18:10
4
0

这应该作为EF6但是我的测试EFCore.

我已经做了一些事情有点类似于此,当我需要修改所有DbSets实现一个具体的界面。

你有两个选择对于你的情况。 由于所有类型没有一个共同基本类型(其他比 object),可以重构产生的那些类提取的共同属性为基类(的 Id, NameType 性)。

在这里,我假设你的 Coffee1Coffee2 表格只有该实体类型 Coffee1Coffee2 分别。

备选案文1:

"重构"类和提取这些共同的特性

public partial class Coffee1 : BaseCoffee {}
public partial class Coffee2 : BaseCoffee {}
public abstract class BaseCoffee
{
  public int Id { get; set; }
  public string Name { get; set; }
  public string Type { get; set; }
}

然后您的查询是这样的

var dbSets = ctxCoin.GetType().GetProperties()
    .Where(p => p.PropertyType.IsAssignableTo(typeof(IQueryable<BaseCoffee>)))
    .Select(set => set.GetValue(ctxCoin))
    .Cast<IQueryable<BaseCoffee>>();

var coffeeList = new ObservableCollection<GenericCoffeeList>();

foreach (var coffee in dbSets)
{
    var query = coffee.Select(c => new GenericCoffeeList { CoffeeCatalogId = c.Id, Name = c.Name, Type = c.Type });

    foreach (var c in query)
    {
        coffeeList.Add(c);
    }
}

这一选项是更多的类型安全和不易出错。

备选2:

使用上的反射 IQueryable<object>

保持你的模型相同,并使用这样的:

var dbSets = ctxCoin.GetType().GetProperties()
    .Where(p => p.PropertyType.IsAssignableTo(typeof(IQueryable<object>)))
    .Select(set => set.GetValue(ctxCoin))
    .Cast<IQueryable<object>>();

var coffeeList = new ObservableCollection<GenericCoffeeList>();

foreach (var queryableObject in dbSets)
{
    var query = queryableObject.Select(GenerateGenericCoffee);

    foreach (var c in query)
    {
        coffeeList.Add(c);
    }
}

GenerateGenericCoffee 辅助方法

GenericCoffeeList GenerateGenericCoffee(object coffeeObject)
{
    var objType = coffeeObject.GetType();

    return new GenericCoffeeList
    {
        CoffeeCatalogId = GetProperty<int>("Id"),
        Name = GetProperty<string>("Name"),
        Type = GetProperty<string>("Type"),
    };

    T GetProperty<T>(string name)
    {
        return (T)objType.GetProperty(name).GetValue(coffeeObject);
    }
}

如果 所有 的模型包含 Id, NameType你会好起来否则你会需要检查这些属性存在之前,首先让 GenericCoffeeList 的项目。

2021-11-18 00:47:02

汉克,谢谢你的代码。 问题在哪里你得到的BaseCoffee?
Bryan K

该DbSets在你的上下文ctxCoin,做所有类型的论据那些具有相同的基类或他们只是发生在具有同样的属性? 即你有 DbSet<Class1> Coffee1 { get; set; }DbSet<Class2> Coffee2 { get; set; },1级和2级都有基类 BaseCoffee 与的性质 Id, NameType.
Hank McCord

汉克,我用enitity框架,以产生类文件,他们不共享一个基类。 该框架创造一个称为代码的第CoffeeCatalogContext. 我用它来访问的分类创造的框架。 我也使用EF核心
Bryan K

@BryanK我重写了我的答案给你更多的选择,反映情况。 我们希望,这有助于!
Hank McCord

汉克。 感谢的代码。 我没有methos IsAssignableTo. 我的程序是blazor和c#体框架的核心。 从什么我可以告诉IsAssignableTo是一个。净的方法。
Bryan K

@BryanK这是一个较新的。净5和6便利的方法。 你可以使用其双 typeof(IQueryable<object>).IsAssignableFrom(p.PropertyType) 代替。 这个已经提供。NETFramework.
Hank McCord

我会给它一试。 感谢您的帮助。
Bryan K

汉克,我没有得到任何结果,从这一部分代码并不能找出原因。 var dbSets=ctxCoin.GetType().GetProperties().在哪里(p=>。PropertyType.IsAssignableFrom(类型(IQueryable<目>))).选择(set=>集。获取名(ctxCoin)).投<IQueryable<目>>();
Bryan K
0

我认为,你创建的遗传类的查询。 当你改变目(移),查询执行对象(移).

public class QueryRepo<TEntity> where TEntity : class
{
    private readonly ctxCoin;
    public QueryRepo(){
        ctxCoin = new CtxCoin();
    }

    public IEnumerable<GenericCoffeeList> GetCoffeeList()
    {
        var entity = ctxCoin.Set<TEntity>();
        return (from c in entity
            select new GenericCoffeeList
            {
                CoffeeCatalogId = c.Id,
                Name = c.Name,
                Type = c.Type
            }).ToList();
    }
}
2021-11-17 07:31:06

请试代码之前发布。
Gert Arnold

谢谢你盖尔 我可能会错过有些事情. 我写的没有ide。
karagoz

主要是化妆品的变化。 仍然没有编译。
Gert Arnold

我说的是没编写有一个编译器。 你觉得这代码的框有意义吗?
karagoz

那么把它写在IDE和测试。 我们都应该这样做(以及太少的人做的,不幸的是). 如果它没有汇编这没有意义。
Gert Arnold
0

我个人会尝试采用一个通用的方法与labda其是用于转换不同类型的咖啡 GenericCoffeeList.

public IEnumerable<GenericCoffeeList> GetCoffeeList<TCoffee>(Func<TCoffee, GenericCoffeeList> toGenericCoffeeList)
{
    return ctxCoin.Set<TCoffee>()
        .Select(coffee => toGenericCoffeeList(coffee)
        .ToList();
}

这样做可以减少代码需要和唯一的事情,需要duplciated是的功能是通过为 toGenericCoffeeList 但也不需要重构200多个课程,以实现一个接口。

这种方法可以适应这取决于你需要做什么(我不是很确定什么你的方法是应该做的因为 coffeeList 是从来没有和使用 coinList 是永远不会宣布)

2021-12-15 12:00:08

Nannana,可以TCoffee是一个串通过?
Bryan K

没有它需要的类型你想要查询这将被用来作为 GetCoffeeList<Coffee1>(coffee1 => new GenericCoffeeList { CoffeeCatalogId = coffee1 .Id, Name = coffee1 .Name, Type = coffee1 .Type })
Nannanas

这就是我的想法。 这就是我想要避免的。 我有200多TEntites所以我在寻找一个解决方案,我没有硬代码的每一个。
Bryan K
0

你可以映一种类型的另一映射领域这样的:

public static Expression<Func<T, R>> MapFields<T, R>(IDictionary<string, string> fieldNamesMapping) 
            where R: new()
{
    var parameter = Expression.Parameter(typeof(T), "o");  
             
    return Expression.Lambda<Func<T, R>>(
        Expression.MemberInit(
            Expression.New(typeof(R)), 
            GetMemberBindings<T,R>(fieldNamesMapping, parameter)), 
        parameter);
}
      

private static IEnumerable<MemberBinding> GetMemberBindings<T,R>(IDictionary<string, string> fieldNamesMapping,
    ParameterExpression parameter) 
        => fieldNamesMapping
            .Select(o => (MemberBinding)Expression.Bind(
                typeof(R).GetProperty(o.Value) ?? throw new InvalidOperationException(), 
                Expression.Property(parameter, typeof(T).GetProperty(o.Key) ?? throw new InvalidOperationException())));

这个代码假定类型的属性,与类似但不同的名称。 因此,该词典有相应的filednames.

如果该领域有相同的名字当然,你可以推断性使用的反思。

的使用情况是这样的:

var toBeMapped = new List<FooA> {
                new FooA {A = 1, B = 2, C = 3},
                new FooA {A = 4, B = 5, C = 6},
                new FooA {A = 7, B = 8, C = 9},
                new FooA {A = 10, B = 11, C = 12}
            };

            var result = toBeMapped.AsQueryable().Select(
                MemberBindingExpressions.MapFields<FooA, FooB>(
                    new Dictionary<string, string> {["A"] = "A", ["B"] = "E"})).ToList();

            result[0].Should().Be(new FooB {A = 1, E = 2});
            result[3].Should().Be(new FooB { A = 10, E = 11 });
2021-12-15 14:33:41

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................