2015-04-04 60 views
0

比方說,我有以下型號:地圖代表從模型到實體

class Foo 
{ 
    public delegate void Bar(); 
    public Bar MyBar { get; set; } 
} 

而且我想這個映射到我的實體:

class FooEntity 
{ 
    public delegate void Bar(); 
    public Bar MyBar { get; set; } 
} 

這是如何完成的?我一直在使用Automapper嘗試:

對我來說,有數據推動這一委託,因爲有數百種不同的方法,我需要能夠取決於MyBar值之間切換是很重要的。有什麼想法嗎?

編輯:

public delegate void Bar(object obj); 

public class Foo 
{ 
    public Bar MyBar { get; set; } 
} 

public class FooEntity 
{ 
    public Bar MyBar { get; set; } 
} 

現在我收到此:錯誤3004:OK,所以這不再移動委託了每一類的範圍之後,從模型映射到實體時拋出異常問題在從第6行開始映射片段:沒有爲Set Foos中的屬性FooEntity.MyBar指定映射。當鍵入[Project.MyDbContext.FooEntity]時,具有鍵(PK)的實體將不會往返。

我的數據庫環境的代碼如下所示:

class MyDbContext : DbContext 
{ 
    DbSet<FooEntity> Foos { get; set; } 
} 

我這個保存到數據庫:

public static class Test() 
{ 
    var foo = new Foo { MyBar = MyFancyDelegate }; 
    using (var context = new MyDbContext()) 
    { 
     context.Foos.Add(Mapper.Map<FooEntity>(foo)); 
     context.SaveChanges(); 
    } 
} 

public static void MyFancyDelegate(object obj) 
{ 
    Console.Write("test"); 
} 

是我的問題只是什麼,我試圖做的?是否無法將委託方法保存到SQL表中?

+0

現在你不能在s SQL表中保存一個* function *(或一個委託) - 最糟糕的情況是這意味着在這個確切的時間點序列化所有的程序(代碼)和內存(狀態) – Carsten 2015-04-04 08:16:51

+0

所以解決方案是很明顯,想想你需要什麼樣的數據來重新創建你的'Bar'並將其序列化到你的SQL表中;) – Carsten 2015-04-04 08:17:49

+0

問題是我需要這個委託來做很多非常不同的事情。我試圖避免讓一個類專門用於存儲靜態方法,但是如果我不能將它們存儲在SQL中,我沒有辦法解決這個問題。 – Kjata30 2015-04-04 08:21:36

回答

1

正如在評論中提到的那樣,不可能以我嘗試的方式在SQL中存儲委託。

相反,有一些可以用來解決問題的兩種方法:

  • 序列化委託指針。然後可以將對象byte[]轉換爲字符串並存儲。當檢索到該值時,可以將其轉換回byte[]對象(使用Convert.ToBase64StringConvert.FromBase64String進行轉換)。這種方法的優點是你不需要任何形式的代碼即時編譯;你只是找到一個你已經有權訪問的代碼的指針。當然缺點是如果你改變了方法的簽名,你的指針就會中斷。

  • 將代碼文本本身存儲爲一個字符串,然後使用System.CodeDom或其他一些編譯庫實時編譯它。這種方法的優點是你看到的是你得到的;您可以查看存儲器中的代碼,並且可以在應用程序的上下文之外操作它。缺點:你的代碼如果它自己的作用域不能引用外部對象,並且你知道代碼實際上可以正常運行(因爲它現在在你的源代碼控制之外被存儲和訪問)就失去了安全性。

1

您可以用一個可以包含委託方法代碼的字符串替換委託。 然後添加一個「get only property」或一個方法,將字符串屬性轉換爲使用Roslyn的c#方法。

+0

這是唯一能以我想要控制代碼的方式工作的方法。我已經序列化委託指針並將指針轉換爲要存儲的字符串,但是如果方法或其簽名更改時檢索指針時會遇到爆炸問題。 – Kjata30 2015-04-08 15:48:04