मैं प्रोजेक्ट डेटा रिपोजिटरी में ऑब्जेक्ट मैपिंग को समाहित करने का प्रयास कर रहा हूं। शायद ईएफ आवश्यक अवशोषण का स्तर प्रदान करेगा, लेकिन इस कारण से मैं लिंक से एसक्यूएल का उपयोग कर रहा हूं।लिंक से SQL डेटा पहुंच को समाहित करने का सबसे अच्छा तरीका क्या है?
public List<ModUser> GetUsers() {
Users.Select(MapUser).ToList();
}
public Expression<Func<User, ModUser>> MapUser {
get {
return u => new ModUser() {
UserId = u.User_Id,
UserResources = u.Resources(MapResource)
}
}
}
public Expression<Func<Resource, ModResource>> MapResource { ...
कोड विफल हो जाएगा के बाद से मैं कर रहा हूँ के रूप में मैं MapResource अभिव्यक्ति फोन नहीं कर सकते हैं: निम्नलिखित कोड ModUser वस्तुओं की एक सूची है, जहां ModUser POCO है कि भंडार को उजागर करता है के रूप में डेटाबेस में उन वापस जाने के लिए करना है इसे एक और अभिव्यक्ति के अंदर से कॉल करने की कोशिश कर रहा है। मैंने u => नए ModResource() के साथ 'MapResource' को प्रतिस्थापित करके, फिर इस प्लेसहोल्डर नोड को ढूंढने और इसे MapResource अभिव्यक्ति के साथ बदलने के लिए ExpressionVisitor का उपयोग करके इसे प्राप्त करने में कामयाब रहा है।
मैं भी इसी तरह के मुद्दों जब मैं केवल एक प्रॉपर्टी है, यानी UserResource = MapResource से जुड़े एक अभिव्यक्ति के साथ ModUser की संपत्ति आवंटित करने के लिए प्रयास करें। अभिव्यक्ति वर्ग पर विधियों का उपयोग करके आवश्यक अभिव्यक्तियों को मैन्युअल रूप से संयोजित करके मैंने इस दूसरे मुद्दे को प्राप्त करने में कामयाब रहा है।
मुझे पता है कि मैं ऊपर कोड को बदल सकता है
UserResources = u.Resources(r => MapResource.Compile().Invoke(r));
लेकिन तब करने के लिए अंतिम SQL क्वेरी के बाद से हम कर रहे हैं, आर के सभी गुण, न कि केवल वे MapResouce द्वारा आवश्यक प्राप्त करने के लिए की आवश्यकता होगी उत्पादित अब एक समारोह से निपटने। साथ ही, MapResouce को आर पर आगे की टेबल तक पहुंच की आवश्यकता होनी चाहिए, यह संभव नहीं होगा क्योंकि इसे किसी फ़ंक्शन के रूप में उपयोग नहीं किया जा रहा है। मैं DeferredLoadingEnabled को सत्य पर सेट कर सकता था लेकिन जो भी आवश्यक तालिकाओं के साथ जुड़ने के लिए मुख्य क्वेरी को संशोधित करने के बजाय व्यक्तिगत प्रश्नों की एक बड़ी संख्या को दूर कर देगा।
क्या किसी को पता है, तो इन आपरेशनों नेट के भविष्य के संस्करणों में आसान हो जा रहे हैं या मैं गलत तरीके से इस बारे में जा रहा हूँ है? मुझे वास्तव में लिंक और अभिव्यक्ति की विशेषताएं पसंद हैं, मेरी इच्छा है कि मैं उन्हें अधिक पठनीय कोड का उपयोग करके नियोजित कर सकूं।
अपडेट किया गया
सोचा मैं कैसे मैं भाव अधिक composable बना दिया है के कुछ उदाहरण जोड़ सकते हैं। वे संक्षिप्त नहीं हैं, लेकिन उन्हें नौकरी मिलती है।
public Expression<Func<User, ModUser>> MapUser {
get {
Expression<Func<User, ModUser>> mapUser = u => new ModUser() {
UserId = u.User_Id,
UserResources = u.Resources(r => new ModResource())
};
return mapUser.MapResources(this);
}
}
public Expression<Func<Resource, ModResource>> MapResource { ... }
public static Expression<Func<T0, T1>> MapResources<T0, T1>(this Expression<Func<T0, T1>> exp, DataContext dc) {
return exp.Visit<MethodCallExpression, Expression<Func<T0, T1>>>(m => {
if(m.Arguments.Count > 1 && m.Arguments[1].Type == typeof(Func<DataContext.Resource, ModResource>)) { //Find a select statement that has the sub expression as an argument
//The resource mapping expression will require the Resource object, which is obtained here
ParameterExpression resourceParam = ((LambdaExpression)m.Arguments[1]).Parameters[0];
return Expression.Call(m.Method, m.Arguments[0], //The first argument is the record selection for the 'select' method
Expression.Lambda<Func<DataContext.Resource, ModResource>>(//Provide the proper mapping expression as the projection for the 'select' method
Expression.Invoke(dc.MapResource, resourceParam),
resourceParam)
);
}
return m;
});
}
तो मैं यहाँ क्या कर रहा हूं? ध्यान दें कि MapUser के इस संस्करण में मैं ModResource ऑब्जेक्ट को सही तरीके से नहीं बनाता, मैं बस एक डमी संस्करण बना देता हूं। मैं फिर एक अभिव्यक्ति विज़िटर विधि को कॉल करता हूं जो डमी कॉल की तलाश करता है और इसे उस स्थान से बदल देता है जिसे मैं मूल रूप से वहां चाहता था। मेरे लिए ऐसा लगता है कि अभिव्यक्ति वाक्यविन्यास की कमी है क्योंकि मैं अनिवार्य रूप से अभिव्यक्ति वृक्ष का निर्माण करने में सक्षम हूं जिसे मैं मूल रूप से चाहता था, लेकिन मुझे वास्तव में पेड़ को ऐसा करने के लिए करना है। नीचे एक और वैकल्पिक हल मैं पाया है कि विलक्षण मामले से संबंधित है:
public Expression<Func<User, ModUser>> MapUser {
get {
Expression<Func<User, ModResource, ModUser>> mapUser = (u, resource) => new ModUser() {
UserId = u.User_Id,
UserResource = resource;
}
return mapUser.CollapseArgument(MapResource, user => user.MainResource);
}
}
public Expression<Func<Resource, ModResource>> MapResource { ... }
public static Expression<Func<T0, T3>> CollapseArgument<T0, T1, T2, T3>(this Expression<Func<T0, T1, T3>> exp, Expression<Func<T2, T1>> exp0, Expression<Func<T0, T2>> exp1) {
var param0 = Expression.Parameter(typeof(T0), "p0");
var argExp = Expression.Invoke(exp0, Expression.Invoke(exp1, param0));
return Expression.Lambda<Func<T0, T3>>(
Expression.Invoke(exp, param0, argExp),
param0);
}
यह दूसरा उदाहरण मुझे पता है कि मैं उपयोगकर्ता डेटा से संसाधन डेटा प्राप्त कर सकते हैं में, लेकिन मैं नहीं कर सकते हैं "इनलाइन" करने के लिए एक अभिव्यक्ति यह दिखाएं कि संसाधन डेटा को संसाधन पीओसीओ में कैसे करें और मानचित्र करें। लेकिन मैं मैन्युअल रूप से एक अभिव्यक्ति वृक्ष बना सकता हूं जिसे पहले से मैप किए गए संसाधन POCO दिया गया है और इसका उपयोग करें। मैं फिर एक और अभिव्यक्ति बना सकता हूं जो दिखाता है कि उपयोगकर्ता से संसाधन कच्चे डेटा को कैसे प्राप्त किया जाए और अंतिम अभिव्यक्ति जो दिखाती है कि कच्चे संसाधन डेटा को संसाधन POCO में कैसे मैप करना है। अब यह कल्पना की जा सकती है कि मैं इस जानकारी को एक अभिव्यक्ति वृक्ष में इस तरह से जोड़ सकता हूं कि संसाधन विशिष्ट पैरामीटर से "ध्वस्त हो जाता है" क्योंकि मैं इसे प्राथमिक उपयोगकर्ता पैरामीटर से प्राप्त कर सकता हूं। यह उपरोक्त कोड है।
तो मुझे अभिव्यक्तियों को अत्यधिक संगत बनाने के तरीके मिल गए हैं ...यह सिर्फ साफ महसूस नहीं करता है।
nhibernate @chris उपयोग नहीं किया है, लेकिन यह "कोड" xml फ़ाइलें में मैपिंग के लिए ले जाया नहीं है? – eglasius
फ्लुएंट एनएचबेर्नेट का उपयोग करें - फिर आपको एक्सएमएल के बजाय कोड प्राप्त होता है, जिसमें सभी रिफैक्टरिंग/संकलन समय सत्यापन की अपेक्षा होती है। –
मैं वास्तव में यहां एक लिंक से SQL समाधान की तलाश में हूं क्योंकि एनएचबीर्नेट में जाने के लिए इस प्रोजेक्ट का विकल्प नहीं है। – LaserJesus