2013-11-22 57 views
0

的總體思路,從建立一個控制,這將與任何數據庫對象的工作開始了。 數據庫經由LINQ訪問以SQL,和數據庫對象是自動生成的,從現有的數據庫。如何讓派生類使用基類的屬性?

爲了與這些對象的控制工作中,我用一個基本接口,所有自動生成的對象繼承。所以這個控件實際上可以和這個接口一起工

在第一這個接口應該提供:

  1. 獲取對象
  2. 表達式的標識符(主鍵),這將返回該標識符,如果通孔的一個實例編譯和被稱爲能力反對

所以這個樣子:

public interface IEntity<TEntity, TEntityId> 
    where TEntity : IEntity<TEntity, TEntityId> 
    where TEntityId : IEquatable<TEntityId> 
{ 
    Expression<Func<TEntity, TEntityId>> GetIdExpression(); 
    TEntityId EntityId { get; } 
} 

然後一個數據庫對象的類定義看起來像:

//let it be the auto-generated part: 
public partial class Entity1 
{ 
    public Guid UId { get; set; } 
} 
//and the manual part: 
public partial class Entity1 : IEntity<Entity1, Guid> 
{ 
    public Expression<Func<Entity1, Guid>> GetIdExpression() 
    { 
     return (Expression<Func<Entity1, Guid>>)(se => se.UId); 
    } 
    public Guid EntityId 
    { 
     get { return this.UId; } 
    } 
} 

我們可以測試一下:

var e1 = new Entity1(); 
e1.UId = Guid.NewGuid(); 
Console.WriteLine(e1.UId); 
Console.WriteLine(e1.GetIdExpression().Compile()(e1)); 

這兩條線的輸出是相等的。沒關係。

接下來的想法是,所有的數據庫對象的大部分份額有int標識與名稱Id。這將是更好的避免編輯他們每個人的,也就是不寫一個和實施IEntity<TEntity, TEntityId>相同的代碼。

至於我需要指定該接口的實現,我需要一個類。 現在我結束了

public class IntEntity<TEntity> : IEntity<TEntity, int> 
     where TEntity : IntEntity<TEntity> 
{ 
    public int Id { get; set; } 

    public Expression<Func<TEntity, int>> GetIdExpression() 
    { 
     return (Expression<Func<TEntity, int>>)(e => e.Id); 
    } 

    public int EntityId 
    { 
     get { return this.Id; } 
    } 
} 

那麼數據庫對象類會從中獲得:

//let it be the auto-generated part: 
public partial class Entity2 
{ 
    public int Id { get; set; } 
} 
//and the manual part: 
public partial class Entity2 : IntEntity<Entity2> 
{ 
} 

現在已經很明顯,那IdEntity2不隱藏IntEntity<TEntity>Id。這也證明了同樣的試驗:

var re = new Entity2(); 
re.Id = 5; 
Console.WriteLine(re.Id); //5 
Console.WriteLine(re.GetIdExpression().Compile()(re)); //0 

所以這種解決方案是錯誤的... 我也tryed作出IntEntity<TEntity>抽象,但顯然沒有,因爲在Entity2Id在自動生成的部分定義,我不能讓它override基類的abstractId

有什麼我可以做的,使所有的數據庫對象int Id使用基地IntEntity<TEntity>類的Id。或者,也許,反之亦然......

主要這裏的一點是,通過GetIdExpression返回表達的形式應該爲e => e.Id,因爲這expresion後來在LINQ用於SQL查詢,因此LINQ應該能夠翻譯它到一個正確的SQL查詢。

+0

那麼爲什麼你需要在'Entity2'和'IntEntity '他們的,而不是隻有一個'id'財產? – Grundy

+0

作爲解決方案的變種 - 在IntEntity 關鍵字'虛擬'中添加到'Id'並在'Entity2'中覆蓋'Id''覆蓋' – Grundy

+0

@Grundy'Entity2'中的''Id'由LINQ to SQL自動生成。我無法修改它的聲明。 – horgh

回答

0

我不知道這正是你想要的,但你可以嘗試這樣做

public abstract class IntEntity<TEntity> : IEntity<TEntity, int> 
    where TEntity : IntEntity<TEntity> 
{ 
    public abstract Expression<Func<TEntity, int>> GetIdExpression(); 
    public abstract int EntityId 
    { 
     get; 
    } 
} 

public partial class Entity2 
{ 
    public int Id { get; set; } 
} 
//and the manual part: 
public partial class Entity2 : IntEntity<Entity2> 
{ 
    public override int EntityId 
    { 
     get { return this.Id; } 
    } 

    public override Expression<Func<Entity2, int>> GetIdExpression() 
    { 
     return (Expression<Func<TEntity, int>>)(e => e.Id); 
    } 
} 

其實沒有overridevirtual你不能在基類中獲得場派生類的方法
樣品上面實際上等於第一個樣品

UPDATE

的變通方法,您可以添加甲基OD SETID是設置在ID派生和基類這樣

public class IntEntity<TEntity> : IEntity<TEntity, int> 
    where TEntity : IntEntity<TEntity> 
{ 
    public int Id { get; set; } 

    public Expression<Func<TEntity, int>> GetIdExpression() 
    { 
     return (Expression<Func<TEntity, int>>)(e => e.Id); 
    } 

    public int EntityId 
    { 
     get { return this.Id; } 
    } 
} 

//let it be the auto-generated part: 
public partial class Entity2 
{ 
    public int Id { get; set; } 
} 
//and the manual part: 
public partial class Entity2 : IntEntity<Entity2> 
{ 
    public void SetId(int id) 
    { 
     Id = id; 
     base.Id = id; 
    } 
} 

var re = new Entity2(); 
re.SetId(5); 
Console.WriteLine(re.Id); //5 
Console.WriteLine(re.GetIdExpression().Compile()(re)); //5 
+0

這完全不是...... – horgh

+0

@horgh你是什麼意思? – Grundy

+0

我的意思是,我說什麼......這根本解決不了問題 – horgh

相關問題