LINQ संस्थाओं के लिए परिवर्तन इकाई के क्रम में

0

सवाल

मैं एक सवाल है. मैं एक dbContext है कि 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), तुम सकता है refactor उत्पन्न उन वर्गों को निकालने के लिए आम गुण के लिए एक आधार वर्ग (के Id, Nameहै , और Type गुण).

मैं यहाँ मान रहा हूँ अपने Coffee1 और Coffee2 मेज सिर्फ इकाई प्रकार Coffee1 और Coffee2 क्रमश:.

विकल्प 1:

Refactor वर्गों और निकालने के उन आम गुण

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, Nameहै , और Type, आप ठीक हो जाएगा अन्यथा आप की आवश्यकता होगी करने के लिए उन लोगों की जांच गुण मौजूद हैं पहली बनाने से पहले GenericCoffeeList आइटम.

2021-11-18 00:47:02

हांक, धन्यवाद के लिए कोड. सवाल कर रहे हैं, जहां आप हो रही BaseCoffee?
Bryan K

के DbSets पर अपने संदर्भ के ctxCoin, सभी प्रकार तर्क करने के लिए उन लोगों के ही आधार वर्ग या वे बस होने के लिए एक ही गुण है? यानी आप DbSet<Class1> Coffee1 { get; set; } और DbSet<Class2> Coffee2 { get; set; }, और Class1 और Class2 दोनों आधार वर्ग BaseCoffee गुणों के साथ Id, Nameहै , और Type.
Hank McCord

हांक, मैं का इस्तेमाल किया enitity रूपरेखा उत्पन्न करने के लिए वर्ग फ़ाइलें वे नहीं एक आधार वर्ग । रूपरेखा बनाता है एक dbContext कहा जाता CoffeeCatalogContext. मैं इसे का उपयोग करें का उपयोग करने के लिए आंशिक वर्गों के द्वारा बनाई गई रूपरेखा. मैं कर रहा हूँ का उपयोग एफई कोर
Bryan K

@BryanK मैं फिर से लिखा गया है मेरा जवाब देने के लिए आप अधिक विकल्प है कि अपनी स्थिति को प्रतिबिंबित. उम्मीद है कि इस मदद करता है!
Hank McCord

हांक. धन्यवाद के लिए कोड. मैं नहीं है methos IsAssignableTo. मेरे app है blazor और सी# निकाय framework कोर. से मैं क्या बता सकते हैं IsAssignableTo है .शुद्ध विधि है ।
Bryan K

@BryanK यह एक नए । शुद्ध 5 और 6 सुविधा विधि है । आप उपयोग कर सकते हैं अपनी जुड़वां typeof(IQueryable<object>).IsAssignableFrom(p.PropertyType) के बजाय. यह एक उपलब्ध किया गया है के बाद से .NETFramework.
Hank McCord

मैं इसे एक कोशिश दे दूँगा. धन्यवाद सब तुम्हारी मदद के लिए.
Bryan K

हांक, मैं नहीं कर रहा हूँ किसी भी परिणाम से कोड के इस भाग में और बाहर आंकड़ा क्यों. वार dbSets = ctxCoin.GetType().GetProperties() .जहां(p => पी.PropertyType.IsAssignableFrom(typeof(IQueryable<object>))) .का चयन करें(सेट => सेट.GetValue(ctxCoin)) .कास्ट<IQueryable<object>>();
Bryan K
0

मुझे लगता है, तुम बनाने के लिए आनुवंशिक वर्ग के लिए क्वेरी । जब आप परिवर्तन वस्तु(TEntity), क्वेरी निष्पादित ऑब्जेक्ट के लिए(TEntity).

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

धन्यवाद आप गर्ट. मैं याद कर सकता somethings. मैं ने लिखा के बिना आईडीई.
karagoz

ज्यादातर कॉस्मेटिक परिवर्तन. अभी भी नहीं है संकलन.
Gert Arnold

मैंने कहा है कि आदमी को लिखने के साथ एक संकलक. आपको लगता है कि यह कोड ब्लॉक समझ में आता है ?
karagoz

तो क्या इसे लिखने में एक आईडीई और यह परीक्षण. हम सभी को करना चाहिए कि क्या (और भी कुछ लोग करते हैं, दुर्भाग्य से). यदि यह नहीं करता यह संकलन मतलब नहीं है.
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 लेकिन यह भी की आवश्यकता नहीं refactoring 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

Thats मैं क्या सोचा है. Thats क्या मैं कर रहा हूँ कोशिश कर रहा से बचने के लिए. मैं 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ý
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में