PDA

View Full Version : ايجاد نوع داده mycommerce.commerce.ShoppingCart



bftarane
شنبه 12 فروردین 1391, 17:58 عصر
سلام. من يه فروشگاه که براي کارت خريدش از Profile Provider خود Asp.net استفاه مي کنه دارم.
کدهاي زير در web.config هست.

<profile enabled="true">
<properties>


<add name="Cart" serializeAs="Binary"
type="mycommerce.commerce.ShoppingCart" allowAnonymous="true"/>

</properties>
</profile>
حالا ميخوام از جداول خودم استفاده کنم نه جدول پيش فرض. براي همين دارم روي Custom Profile Provider کار مي کنم. حالا
اگه بخواهيم از Custom Profile Provider استفاده کنيم
براي ايجاد فيلد Cart در جدول چه کار بايد کرد؟
منظورم اينه اگه نوع داده String يا int بود مشکلي وجود نداشت ولي همانطور که مي بينيد در اينجا
Type=mycommerce.commerce.ShoppingCart هستش.
mycommerce.commerce فضاي نام هستش و ShoppingCart هم اسم يه کلاس هست.
من اصطلاحي به نام داده سفارشي شنيدم آيا اين راه حلش هست؟

و اگه اين کار شدني بود و انجام شد در مورد اون قسمت serializeAs="Binary" هم بايد کار خاصي انجام داد يا مثل وقتي که دارم از ProfileProvider خود Asp.net استفاده ميکنم باهاش برخورد کنم؟
با توجه به اينکه اين قسمت رو در فضاي نام دارم
[Serializable]
public class ShoppingCart
{

متشکرم از هر کسي که جواب بده.

bftarane
یک شنبه 13 فروردین 1391, 09:57 صبح
خوب تا حالا کسي جواب نداده. پس شايد کسي تا حالا همچنين کاري انجام نداده.
به انگليسي هم سرچ زدم جوابم رو پيدا نکردم.
لطفاً اگه اين کاري نشدني هست يا اگه شدني هست ولي غيرمنطقي هست و ارزش اين همه زحمت رو نداره بهم بگيد تا وقتم رو بيخودي سرش تلف نکنم.

C#.net
یک شنبه 13 فروردین 1391, 11:00 صبح
چند سال پیش باهاش کار کردم، تا اونجا که یادم میاد اطلاعات پراپرتی به صورت key-value در یکی از جداول ذخیره می شن، شما نیازی به تغییر در دیتابیس خودتون ندارید.


<profile>
<properties>
<add name="PostalCode" />
</properties>
</profile>



Profile.PostalCode = txtPostalCode.Text;

به این لینک (http://msdn.microsoft.com/en-us/library/2y3fs9xs.aspx) مراجعه کنید

bftarane
یک شنبه 13 فروردین 1391, 12:04 عصر
تا اونجا که یادم میاد اطلاعات پراپرتی به صورت key-value در یکی از جداول ذخیره می شن، شما نیازی به تغییر در دیتابیس خودتون ندارید.

من با Profile Provieder خود Asp.net کار کردم. در اون حالت من هيچ جدولي خودم درست نکرده بودم و اطلاعات در جدول aspnet_Profile مربوط به خود Asp.net ذخيره ميشد. و فکر مي کنم مطلبي که شما اشاره کرديد همين کاري هست که من قبلاً انجام دادم.
ولي من حالا مي خوام از Custom Profile Provider استفاده کنم و از جدول پيش فرض Asp.net استفاده نکنم. و از لينک زير هم نتيجه گرفتم بايد به ازاي هر پراپرتي بايد يه فيلد در جدول خودم داشته باشم.
اين رو هم بگم که لينک زير کمک کرد و کاستوم پروفايل پروايدر جواب داد ولي با يه همچنين پراپرتي ساده اي:

<properties>
<add name="ZipCode"
allowAnonymous="true" />
که خوب چون type براش مشخص نشده پس String هست و در جدول هم يه فيلد به ازاش درست کردم با نوع varchar.
ولي مشکل من اينه که من الآن با يه type مواجه هستم که يه کلاس هست يعني Type=mycommerce.commerce.ShoppingCart و اين رو نمي دونم بايد چه کار کنم.
http://barnamenevis.org/showthread.php?334255

C#.net
یک شنبه 13 فروردین 1391, 13:23 عصر
خوب من یه نگاهی به سمپل قدیمی خودم انداختم، اجازه بدید کمی وارد جزئیات بشیم، شما تابع های GetPropertyValues و SetPropertyValues رو باید override کرده باشید، درسته؟
کاری که باید بکنید اینه که یه جدول دیگه شامل فیلدهای کلاس ShoppingCart خودتون بسازید(یادتون باشه حتما یه ID هم براش تعریف کنید)
حالا باید در جدول اصلی یه فیلد اینتجر که در حقیقت یه forign key به جدول ShoppingCart هست رو تعریف کنید مثلا به اسم ShoppingCartID

حالا برگریدیم به GetPropertyValues


public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection settingsProperties)
{

string userName = context["UserName"].ToString();
bool isAuthenticated = Convert.ToBoolean(context["IsAuthenticated"]);

SqlConnection sqlConnection = new SqlConnection(connectionString);
SqlCommand sqlCommand = new SqlCommand("ProfileData_Sel", sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlDataReader sqlDataReader = null;

sqlCommand.Parameters.Add("userName", SqlDbType.NVarChar, 50).Value = userName;
sqlCommand.Parameters.Add("applicationName", SqlDbType.NVarChar, 50).Value = applicationName;
sqlCommand.Parameters.Add("isAnonymous", SqlDbType.Bit, 0).Value = !isAuthenticated;

SettingsPropertyValueCollection settingsValues = new SettingsPropertyValueCollection();

try
{
sqlConnection.Open();
sqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.CloseConn ection & CommandBehavior.SingleRow);

sqlDataReader.Read();

foreach (SettingsProperty property in settingsProperties)
{
SettingsPropertyValue settingsPropertyValue = new SettingsPropertyValue(property);


switch (property.Name)
{
case "ShoppingCart":
{
// خواندن شناسه کلید خارجی از پایگاه داده
int id = int.Parse(sqlDataReader["ShoppingCartID"].ToString());

settingsPropertyValue.PropertyValue =
//
//TODO: خواندن اطلاعات متناظر از جدول مربوطه و
// تبدیل به نوع کلاس متناظر
//

}
break;
// ....
default:
throw new Exception("Unsupported property.");
}

settingsValues.Add(settingsPropertyValue);
}
}
catch (SqlException e)
{
throw new Exception(e.Message);
}
finally
{
if (sqlDataReader != null)
{
sqlDataReader.Close();
}
}

return settingsValues;
}


کار مشابه هم باید برای SetPropertyValues صورت بگیره، توجه کنید PropertyValue از نوع object هست در نتیجه می تونید کلاس ShoppingCart رو بهش تخصیص بدید
امیدوارم بهتون ایده کلی رو داده باشم

شاید این لینک (http://msdn.microsoft.com/en-us/library/d8b58y5d.aspx)هم به کارتون بیاد

bftarane
یک شنبه 13 فروردین 1391, 16:54 عصر
خيلي پستتون کمک کننده بود ولي هنوز من به جوابم نرسيدم.

شما تابع های GetPropertyValues و SetPropertyValues رو باید override کرده باشید، درسته؟

در واقع اين توابع در يکي از لينکهاي زير override شدن.
خوب من دارم از دو تا لينک زير کمک مي گيرم براي ساخت Custom Profile Provider
http://msdn.microsoft.com/en-us/library/8zs47k7y.aspx
http://msdn.microsoft.com/en-us/library/ta63b872.aspx
و قصد داشتم بعد از اينکه فيلد Cart رو در جدول درست کردم برم سراغ تکميل کردن تابع هاي مورد نياز در مورد Cart
خوب کدها در مورد پراپرتي ZipCode وجود داشت و کافي بود من اونها رو کمي تغيير بدم در مورد پراپرتي Cart
منظورم اينه که اگه فيلد Cart رو ايجاد کنم بعد مي تونم برم و اين کدها رو بنويسم در کلاس کاستوم پروفايل پروايدر
مثلاً در قسمت GetPropertyValues در قسمت Switchاضافه کنم

case "Cart":
pv.PropertyValue = GetCart(username, isAuthenticated);
و در قسمت SetPropertyValues اضافه کنم

case="Cart":
SetCart(uniqueID,(??????????)pv.PropertyValue);
(يعني تقريباً همون محدوده اي که شما با رنگ سبز نوشتيد اين کدهايي که در بالا نوشتم رو بنويسم)
و توابع SetCart و GetCart رو هم با الگوبرداري از SetZipCode و GetZipCode بنويسم.
که جاي علامت سوالا فکر مي کنم با توجه به اشاره اي که به object کرديد ميشه mycommerce.commerce.ShoppingCart رو بزارم.

خوب در لينک اول اين کد رو مي بينيم
<properties>
<add name="ZipCode"
allowAnonymous="true" />
<add name="CityAndState"
provider="AspNetSqlProfileProvider"
allowAnonymous="true" />
<add name="StockSymbols"
type="System.Collections.ArrayList"
allowAnonymous="true" />
</properties>
و مي بينيم يه جدول ايجاد کرده به اسم ProfileData و درونش يه فيلد به اسم ZipCode ايجاد کرده.
خوب حالا کاري که من مي خوام بکنم اينه که کد زير رو اضافه کنم در قسمت <properties>
<add name="Cart" serializeAs="Binary"
type="mycommerce.commerce.ShoppingCart" allowAnonymous="true"/>
خوب چيزي که فکر مي کنم بايد انجام بدم اينه که بايد يه فيلد به اسم Cart بايد به جدول ProfileData اضافه کنم (با توجه به name=Cart)
چون فکر مي کنم Cart و ZipCode هر دو پراپرتي هستند و در يک سطح قرار دارند و هر کاري که در مورد ZipCode صورت گرفته مي تونه در مورد Cart هم صورت بگيره
من مي خوام جدول زير رو داشته باشم
85040
UniqID هم کليد خارجي هستش. جدول اصلي هم Profiles هستش که UniqID اونجا کليد اوليه هست.
ولي مشکل اينجاست که نمي دونم Datatype رو چي قرار بدم.





کاری که باید بکنید اینه که یه جدول دیگه شامل فیلدهای کلاس ShoppingCart خودتون بسازید(یادتون باشه حتما یه ID هم براش تعریف کنید)
حالا باید در جدول اصلی یه فیلد اینتجر که در حقیقت یه forign key به جدول ShoppingCart هست رو تعریف کنید مثلا به اسم


من براي ذخيره سفارش ها دو تا جدول دارم به نامهاي orders و orderLines.

85042

85041

اين هم يه جدول که عکس محصول، عنوانش، جزئيات و... توش ذخيره ميشه.
85043

من نمي خوام تغيير عمده در جدولهام بدم بنابراين تنها جدولايي که مي خوام اضافه کنم دو تا جدول به اسم Profiles و ProfileData هست.

C#.net
یک شنبه 13 فروردین 1391, 17:04 عصر
ولي مشکل اينجاست که نمي دونم Datatype رو چي قرار بدم.
داستان این هست که در sql دیتا تایپ های پیچیده ای مثل کلاس قابل تعریف نیست، پس باید یه جوری(از طریق foreign key) باید اطلاعات رو ارتباط داد، با توجه به طراحی شما باید جای Cart از foreign key مربوط به جدول orders یعنی orderID استفاده کنید، بعد در متدهای یاد شده از طریق بازیابی این کلید خارجی، کلاس ShoppingCart رو با اطلاعات پر می کنید و به عنوان خروجی پراپرتی برمی گردونید.

در حقیقت این یه روش هست که اگر روش کار کنید به جواب می رسید، ولی تنها راه حل ممکن نیست، من بحث رو بیش تر باز می کنم، کلید کار دو متد GetPropertyValues و SetPropertyValues هستند، وقتی شما کد زیر رو می نویسید:


var x = Profile.Card;


در پشت صحنه متد GetPropertyValues فراخوانی می شه و هرجور که شما درباره پراپرتی Card کد نوشته باشید، بر همون اساس مقدار بر می گردونه و وقتی شما کد زیر رو می نویسید:


Profile.Card = new ShoppingCard{ /* ...*/};


متد SetPropertyValues وظیفه ذخیره کردن این اطلاعات رو داره(شما تصمیم می گیرید به چه فرمی)

به لینکی که در آخر پست قبلیم موجود هست مراجعه کنید و قسمت Working with User-Defined Property Types رو دقیق مطالعه کنید، اینجا پیاده سازی default خود مایکروسافت از تکنیک سریالایز باینری استفاده کرده.




من مي خوام جدول زير رو داشته باشم
85040
UniqID هم کليد خارجي هستش. جدول اصلي هم Profiles هستش که UniqID اونجا کليد اوليه هست.
ولي مشکل اينجاست که نمي دونم Datatype رو چي قرار بدم.



اگه شما هم بخواهید به این صورت پیاده سازی بفرمایید پاسخ پرسش بالا می شه varbinary.

یا اگر بخواهید از serializeAs="Xml" استفاده کنید پاسخ nvarchar(500) می شه(به عنوان مثال)

ولی به نظر من روش اول برای کار شما بهتر هست و پرفورمنس بالاتری خواهد داشت( با توجه به اینکه شما اطلاعات کارت رو در دیتابیس دارید)