我有一個令人討厭的問題,我真的無法理解。如果DbContext被封裝在一個接口中,LINQ查詢無法被翻譯
基本上我有定義的的DbContext如下
public interface ISettingsContext : IDisposable
{
IDbSet<Site> Sites { get; }
IDbSet<SettingGroup> Groups { get; }
IDbSet<SettingProperty> Properties { get; }
int SaveChanges();
}
public class SettingsContext : DbContext, ISettingsContext
{
public SettingsContext(string connectionStringName) : base(connectionStringName)
{
Sites = Set<Site>();
Groups = Set<SettingGroup>();
Properties = Set<SettingProperty>();
}
public SettingsContext() : this("DefaultTestConnectionString") { }
public IDbSet<Site> Sites { get; private set; }
public IDbSet<SettingGroup> Groups { get; private set; }
public IDbSet<SettingProperty> Properties { get; private set; }
#region Model Creation
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
MapSite(modelBuilder.Entity<Site>());
MapGroup(modelBuilder.Entity<SettingGroup>());
MapProperty(modelBuilder.Entity<SettingProperty>());
MapValue(modelBuilder.Entity<SiteSettingValue>());
MapXmlValue(modelBuilder.ComplexType<XmlValue>());
MapXmlType(modelBuilder.ComplexType<XmlTypeDescriptor>());
}
private void MapXmlType(ComplexTypeConfiguration<XmlTypeDescriptor> complexType)
{
complexType.Ignore(t => t.Type);
}
private void MapXmlValue(ComplexTypeConfiguration<XmlValue> complexType)
{
complexType.Ignore(t => t.Value);
}
private void MapValue(EntityTypeConfiguration<SiteSettingValue> entity)
{
entity.HasKey(k => new { k.PropertyId, k.SiteId }).ToTable("SiteValues", "settings");
entity.Property(k => k.PropertyId).HasColumnName("FKPropertyID");
entity.Property(k => k.SiteId).HasColumnName("FKSiteID");
entity.Property(k => k.Value.RawData).HasColumnName("Value").IsMaxLength();
entity.HasRequired(k => k.Site).WithMany(s => s.Settings).HasForeignKey(k => k.SiteId);
entity.HasRequired(k => k.Property).WithMany().HasForeignKey(k => k.PropertyId);
}
private void MapProperty(EntityTypeConfiguration<SettingProperty> entity)
{
entity.HasKey(k => k.Id).ToTable("Properties", "settings");
entity.Property(k => k.Id);
entity.Property(k => k.Name);
entity.Property(k => k.GroupId).HasColumnName("FKGroupID");
entity.Property(k => k.PropertyDescriptor.RawData).HasColumnName("TypeDescriptor").IsMaxLength();
entity.Property(k => k.DefaultValue.RawData).HasColumnName("DefaultValue").IsMaxLength();
entity.HasRequired(k => k.Group).WithMany(k => k.Properties).HasForeignKey(k => k.GroupId);
}
private void MapGroup(EntityTypeConfiguration<SettingGroup> entity)
{
entity.HasKey(k => k.Id).ToTable("Groups", "settings");
entity.Property(k => k.Id);
entity.Property(k => k.Name);
entity.HasMany(k => k.Properties).WithRequired(k => k.Group).HasForeignKey(k => k.GroupId);
}
private void MapSite(EntityTypeConfiguration<Site> entity)
{
entity.HasKey(k => k.Id).ToTable("Sites", "site");
entity.Property(k => k.Id);
entity.Property(k => k.Domain);
}
#endregion
}
由於我在一些測試揹着,我開始在這方面的工作,而無需關心的IoC和DI,所以我直接合作對具體類本身。
所以我寫了這個查詢:
public class SiteSettingsLoader : ILoader<SiteSettingsModel, int> {
...
var qSiteValues = from site in context.Sites
let settings = site.Settings
select new
{
SiteId = site.Id,
Settings = from value in settings
join property in context.Properties on value.PropertyId equals property.Id into props
from property in props
select new
{
PropertyId = property.Id,
Name = property.Name,
GroupId = property.GroupId,
Value = value.Value,
CanBeInherited = property.CanBeInherited
}
};
,一切工作就好了。 當我開始傳遞上下文作爲它實現的接口而不是實際類型時,問題就開始了。
using (ISettingsContext context = new SettingsContext())
using (SiteSettingsLoader loader = new SiteSettingsLoader(context))
{
SiteSettingsStore store = new SiteSettingsStore(loader);
dynamic settings = store.GetItem(1);
}
這是錯誤
無法創建 類型的恆定值 'Settings.Entities.SettingProperty'。在此上下文中僅支持基本類型(如' Int32,String和Guid')。
這怎麼可能?微軟用反射玩弄了一些骯髒的伎倆嗎
編輯: 兩個XmlValue和XmlTypeDescriptor有以下幾種接口的實現,我們用它來自動讀取XML字段的內容轉換成合適的對象。
public interface IXmlProperty
{
string RawData { get; set; }
void Load(string xml);
XDocument ToXml();
}
基本上我們將字段的內容映射到RawData屬性;在其setter和getters中,我們解析/生成包含數據庫XML的字符串。 我知道這是一個醜陋的伎倆,但它工作並完成工作。
哎喲,我無法找到這個問題:S – Kralizek