2017-06-16 70 views
2

我得到了兩個使用相同接口的實體。我想從實體框架兩個結果我得到合併的IKurs一個列表:投射和合並兩個相同接口但不同類型的列表

public async Task<IEnumerable<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>> GetCourses(bool takeXtr) 
{ 
    IEnumerable<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>> result = new List<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>(); 
    if (takeXtr) 
     using (var context = new Context()) 
     { 
      var courses = context.XtrCourses.Include(x=>x.TeachersToCourses).Where(_someCourseFilterForAgs); 
      result.Concat(await courses.ToListAsync()).Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>(); 
     } 

    using (var context = new Context()) 
    { 
     var courses = context.AgsCourses.Include(x=>x.TeachersToCourses).Where(_someCourseFilterForAgs); 
     result.Concat(await courses.ToListAsync()).Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>(); 
    } 
    return result; 
} 

正如你所看到的,我試着用 .Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>()鑄造他們兩個(即引發InvalidCastException)

這些都是我的Course類,既實現IKurs<T1<T2>, T1>但它們的T1和T2是不同的(但是仍然它們使用相同的接口):

public class XtrCourse : Core_Xtr_Course, IKurs<XtrTeacherToCourse, XtrAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    // properties 

    public ICollection<XtrTeacherToCourse> TeachersToCourses { get; set; } 
} 

public class AgsCourse : Core_Ags_Course, IKurs<AgsTeacherToCourse, AgsAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    // properties 

    public ICollection<AgsTeacherToCourse> TeachersToCourses { get; set; } 
} 

public interface IKurs<TTeacherToCourse, TAdditionalTeacherData> 
     where TTeacherToCourse : ITeacherToCourse<TAdditionalTeacherData> 
     where TAdditionalTeacherData: IAdditionalTeacherData 
{ 
    int Nr { get; set; } 

    ICollection<TTeacherToCourse> TeachersToCourses { get; set; } 
} 

public interface ITeacherToCourse<T> where T : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    T AdditionalTeacherData { get; set; } 
} 

public interface IAdditionalTeacherData 
{ 
    // properties 
} 

AgsTeacherToCourseXtrTeacherToCourse都實現ITeacherToCourseAgsTeacherToCourseXtrTeacherToCourse都實現ITeacherToCourse

我怎樣才能將它們合併到一個列表?

實際上,兩個課程列表都來自不同的環境。這就是爲什麼我在GetCourses()兩次啓動上下文。

回答

1

一個主要的問題是

interface ITeacherToCourse<T> where T : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    T AdditionalTeacherData { get; set; } 
} 

class XtrTeacherToCourse : ITeacherToCourse<XtrAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public XtrAdditionalTeacherData AdditionalTeacherData { get; set; } 
} 

class AgsTeacherToCourse : ITeacherToCourse<AgsAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public AgsAdditionalTeacherData AdditionalTeacherData { get; set; } 
} 

接口定義的合同,你只能設置一個值XtrAdditionalTeacherData類型的AdditionalTeacherDataXtrAdditionalTeacherDataAgsAdditionalTeacherDataAgsTeacherToCourse

我們怎樣才能保證這個合同的時候,我們能夠

ITeacherToCourse<IAdditionalTeacherData> ttc = new XtrTeacherToCourse(); 
ttc.AdditionalTeacherData = new AgsAdditionalTeacherData(); 

如果你不想設置AdditionalTeacherData屬性,那麼你可以聲明接口一樣

interface ITeacherToCourse<out T> where T : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    T AdditionalTeacherData { get; } 
} 

AdditionalTeacherData是現在只讀Tout T

現在我們能夠

ITeacherToCourse<IAdditionalTeacherData> ttc; 
ttc = new XtrTeacherToCourse(); 
ttc = new AgsTeacherToCourse(); 

有了它相同的集合。

總接口聲明

interface IAdditionalTeacherData 
{ 

} 

interface ITeacherToCourse<out T> where T : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    T AdditionalTeacherData { get; } 
} 

interface IKurs<out TTeacherToCourse, out TAdditionalTeacherData> 
    where TTeacherToCourse : ITeacherToCourse<TAdditionalTeacherData> 
    where TAdditionalTeacherData : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    IEnumerable<TTeacherToCourse> TeachersToCourses { get; } 
} 

和實現類

class XtrAdditionalTeacherData : IAdditionalTeacherData 
{ 

} 

class XtrTeacherToCourse : ITeacherToCourse<XtrAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public XtrAdditionalTeacherData AdditionalTeacherData { get; set; } 
} 

class XtrCourse : IKurs<XtrTeacherToCourse, XtrAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public ICollection<XtrTeacherToCourse> TeachersToCourses { get; set; } 
    // explicit implementation 
    IEnumerable<XtrTeacherToCourse> IKurs<XtrTeacherToCourse, XtrAdditionalTeacherData>.TeachersToCourses => TeachersToCourses; 
} 

class AgsAdditionalTeacherData : IAdditionalTeacherData 
{ 

} 

class AgsTeacherToCourse : ITeacherToCourse<AgsAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public AgsAdditionalTeacherData AdditionalTeacherData { get; set; } 
} 

class AgsCourse : IKurs<AgsTeacherToCourse, AgsAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public ICollection<AgsTeacherToCourse> TeachersToCourses { get; set; } 
    // explicit implementation 
    IEnumerable<AgsTeacherToCourse> IKurs<AgsTeacherToCourse, AgsAdditionalTeacherData>.TeachersToCourses => TeachersToCourses; 
} 

,現在我們可以在沒有任何投

var collection = new List<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>(); 

collection.Add(new XtrCourse()); 
collection.Add(new AgsCourse()); 
+0

哇。完善。 'out'正是問題所在。 Thx幫助:) –

1

無需鑄造,您可以添加任何IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>到您的清單。

interface IMyclass{} 

    class MyType1 : IMyclass {} 

    class MyType2 : IMyclass {} 

    public class SomeClass 
    { 
     private List<IMyclass> MyList = new List<IMyclass>(); 

     public void DoSomething() 
     { 
      MyList.AddRange(new List<IMyclass> { new MyType1(), new MyType1() }); 
      MyList.AddRange(new List<IMyclass> { new MyType2(), new MyType2() }); 
     } 
    } 
+0

試着用'result.AddRange添加實例(AWAIT courses.ToListAsync());'但這讓我的編譯器哭:(:(參數類型列表不是ssignable to parametertype IEnumerable ,IAdditionalTeacherData >>' - 我想我首先需要投射整個結構呢? –

+0

@MatthiasBurger的東西必須與您的類型。我不得不承認我對你複雜的類型定義感到困惑,但只要你從你的編譯器得到這個錯誤,轉換就不能工作。該錯誤基本上告訴你,鑄造將無法正常工作。 – oerkelens

+0

我仍然不完全知道爲什麼,但Rufo爵士已經發現了這個問題。我需要研究爲什麼我需要在這裏的界面中使用'out'。但thx爲你的幫助:) - 是的,結構混亂。你是對的 - 這不是我的數據庫設計:D –

相關問題