정말 이해할 수없는 불쾌한 문제가 있습니다. 나는 몇 가지 테스트를 수행 된 이후DbContext가 인터페이스에 래핑 된 경우 LINQ 쿼리를 번역 할 수 없습니다.
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
}
을 다음과 같이
은 기본적으로 내가 정의 DbContext을 가지고, 나는 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'등) 만 지원됩니다.
어떻게 가능합니까? Microsoft는 리플렉션을 통해 더러운 속임수를 사용 했습니까?
편집 : XmlValue와 XmlTypeDescriptor 모두 우리가 자동으로 적절한 개체로는 XML 필드의 내용을 읽는 데 사용할 다음과 같은 인터페이스의 구현입니다.
public interface IXmlProperty
{
string RawData { get; set; }
void Load(string xml);
XDocument ToXml();
}
기본적으로 우리는 필드의 내용을 RawData 속성에 매핑합니다. setter와 getter에서 우리는 데이터베이스 용 XML을 포함하는 문자열을 구문 분석/생성합니다. 나는 그것이 추한 속임수라는 것을 알고 있지만 일을 마치고 일을 끝낸다.
아야를 (. 위의 작품이 최고이기 때문에 Eranga의 링크 대답을 upvote에 잊지하지 않는 경우)
, 그 질문을 찾을 수 없습니다 : S를 – Kralizek