新增 connection string
修改剛剛新增的 connection string 的設定
修改 connection string 的值
點選 “Data Access Application Block”
設定預設的資料庫
新增 connection string
修改剛剛新增的 connection string 的設定
修改 connection string 的值
點選 “Data Access Application Block”
設定預設的資料庫
一模一樣的程式(Asp.Net 2.0),在 Windows 2003 上跑就很好,而 Windows 2000 就奇慢無比,差了40倍。
程式碼如下
string strRes = DateTime.Now.ToString("MMMM dd, yyyy HH:mm:ss", DateTimeFormatInfo.InvariantInfo);
Response.Clear();
Response.Write(strRes);
Response.Flush();
Response.End();
查了好久。查過修改 Global.asax.cs,IIS 的權限設定,帳號等。最後,竟然是 Response.Flush(); 這一行的問題。將這一行刪除後,就正常了。
網頁權限不正常的部署
部署網頁程式時,必須使用Copy & Paste,不能 Cut & Paste。一旦使用Cut & Paste,非常容易造成權限的問題。
主要是「網際網路的Guest 帳號」的權限不見了。如下圖。
處理
首先,在出事的目錄上,按右鍵,點擊「內容」
再來,按下方的進階
再來,勾選「以顯示於此套用到子物件的項目,取代所有子項物件上的權限項目」
按「套用」鍵後,會出現下面視窗,請按「是」。
看來,我發現了一個 Linq to SQL 的 bug。
要還原現場,當然要 database 。
CREATE TABLE [dbo].[A]( [AId] [int] NOT NULL, [AName] [char](10) NOT NULL, CONSTRAINT [PK_A] PRIMARY KEY CLUSTERED ( [AName] ASC ), CONSTRAINT [IX_A] UNIQUE NONCLUSTERED ( [AId] ASC ) ) GO INSERT [dbo].[A] ([AId], [AName]) VALUES (1, N'Charles ') go CREATE TABLE [dbo].[A2]( [AId] [int] NOT NULL, [AValue] [varchar](50) NOT NULL, CONSTRAINT [PK_A2] PRIMARY KEY CLUSTERED ( [AId] ASC ) ) GO ALTER TABLE [dbo].[A2] WITH CHECK ADD CONSTRAINT [FK_A2_A] FOREIGN KEY([AId]) REFERENCES [dbo].[A] ([AId]) GO ALTER TABLE [dbo].[A2] CHECK CONSTRAINT [FK_A2_A] GO
注意到,A2.AId 是 reference 到 A.AId。而A.AId 是 unique key,而非 primary key。A 的 primary key 是 AName
再來,就開始拉 dbml ,如下圖
再 create 一個 Console Application,如下
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TestDataContext ctx = new TestDataContext();
A2 a2 = new A2 { AId = 1, AValue = "xxx" };
ctx.A2s.InsertOnSubmit(a2);
ctx.SubmitChanges();
}
}
}
程式錯誤訊息如下:
Type : System.InvalidCastException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Message : Unable to cast object of type 'System.Int32' to type 'System.String'. Source : System.Data.Linq Help link : Data : System.Collections.ListDictionaryInternal TargetSite : Boolean TryCreateKeyFromValues(System.Object[], V ByRef) Stack Trace : at System.Data.Linq.IdentityManager.StandardIdentityManager.SingleKeyManager`2.TryCreateKeyFromValues(Object[] values, V& v) at System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache`2.Find(Object[] keyValues) at System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType type, Object[] keyValues) at System.Data.Linq.CommonDataServices.GetCachedObject(MetaType type, Object[] keyValues) at System.Data.Linq.ChangeProcessor.GetOtherItem(MetaAssociation assoc, Object instance) at System.Data.Linq.ChangeProcessor.BuildEdgeMaps() at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) at System.Data.Linq.DataContext.SubmitChanges()
這個錯誤訊息,真是是令人不敢領教。
其實,這個錯誤,只需要修改 A 的 primary key 為 AId 即可。但實務上,卻非常有可能如上例的資料庫設計。
以發票的例子為例,常常會以發票號碼作為 primary key,而另設一個 ObjectId (int) 作為別的 table 的 reference key,因為 int 的size 較小。
Sql Script 可這裡下載, 而程式碼可這裡下載
目前我已向微軟提出這樣的 bug。這是算是我的第一次呢!
[註] 2008/08/19 MS Linq to SQL team 已經證實這個 issue ,而且會在下一次 release 修正。
以往,要在 IIS 6 新增網站,增加 application 或 application pool ,都必須靠人工由 inetmgr 操作,或寫 script 操作 activeX 元件。
不是非常方便。
學了 .net 後,這些工作並沒有得到改善。原因是 IIS 6 仍然是 unmanaged code。
終於, IIS 7 算是改寫了。因此,可以用下面的程式來新增一個 "MyDemoSite" 網站,port 是 8080。該網站的根目錄是 c:\demoSite。
並建立一個 applicatioin pool 為 "demoPool",且是 intergrated。並將該網站的 application pool 設為 "demoPool"。
(ps: 上一段的文字描述,反而不如程式碼來的清楚)
首先,必須 add reference。必須瀏覽到 C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll
然後再寫下面這一段
ServerManager serverManager = new ServerManager();
serverManager.Sites.Add("MyDemoSite", @"c:\demoSite", 8080);
ApplicationPool pool = serverManager.ApplicationPools.Add("demoPool");
pool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
serverManager.Sites["MyDemoSite"].Applications["/"].ApplicationPoolName = "demoPool";
serverManager.CommitChanges();
這一段程式,必須由具有權限的人來執行。否則會發生例外。
Cannot implicitly convert type IEnumerable<A> to System.Data.Linq.EntitySet. An explicit conversion exists (are you missing a cast?)
這是我開發時發生的問題。
大概是這樣的。
var q = from storeEl in buyerEl.Elements("store")
select new Store
{
StoreId = storeEl.Element("id").Value,
TaxNo = buyerEl.Value,
StoreName = storeEl.Element("cname").Value,
Emails = from sub in storeEl.Elements("mails")
select new StoreEmail
{
StoreId = storeEl.Attribute("id").Value,
Email = sub.Attribute("email").Value
},
};
問題出現在 from sub in 那一段。Emails 是一個 EntitySet<Email>,而非 IEnumerable<Email>,於是發生了錯誤。goole 了一下,找到了一個看來不是很好的方法。
public static class LinqExtension
{
public static EntitySet ToEntitySet(this IEnumerable source) where T : class
{
var es = new EntitySet();
es.AddRange(source);
return es;
}
}
然後,將程式改為
var q = from storeEl in buyerEl.Elements("store")
select new Store
{
StoreId = storeEl.Element("id").Value,
TaxNo = buyerEl.Value,
StoreName = storeEl.Element("cname").Value,
Emails = (from sub in storeEl.Elements("mails")
select new StoreEmail
{
StoreId = storeEl.Attribute("id").Value,
Email = sub.Attribute("email").Value
}).ToEntitySet(),
};
當要研究 Compiler 的特性時,有時需要一些工具來看產生的 assembly 結果。
例如,C# 3.0 的 auto implement property
namespace ClassLibrary1 { class Employee { public int Id { get; private set; } public string Name { get; set; } } }會產生什麼樣的結果呢?
Lutz Roeder's .NET Reflector 這個工具可以讓我們的生活更輕鬆一些。