我正在尝试使用EF 4.1和代码创建数据模型。 我的Poco课程看起来像这样:
public abstract class AttributeBase
{
public int Id { get; set; }
public string Name { get; set; }
public string AttributeDescription { get; set; }
public int Length { get; set; }
public bool AllowNull { get; set; }
public bool DisplayInWeb { get; set; }
}
public class StringListAttribute : AttributeBase
{
public ICollection<StringValue> Values { get; set; }
public StringListAttribute()
{
Values = new List<StringValue>();
}
}
public class StringValue
{
public int StringValueId { get; set; }
public string Value { get; set; }
}
基本思想是StringListAttribute继承自AttributeBase类(其他类也继承自AttributeBase类,但我没有在这篇文章中包含它们)
StringListAttribute类具有StringValues的集合。 (零对多关系)。我在MyContextExtention类中尝试实现的是,每当我想要数据库中的AttributeBase对象列表时,我想获取所有StringListAttribute对象并一次填充它们的StringValue集合。我不想要任何延迟加载。我希望在尽可能少的查询中尽可能多地检索数据。
我的Context类继承自DbContext,我在BraArkivContext类上创建了一个扩展方法
public class MyContext : DbContext
{
public DbSet<AttributeBase> Attributes { get; set; }
public MyContext()
{
Configuration.LazyLoadingEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<StringListAttribute>()
.HasMany(t=>t.Values).WithOptional().WillCascadeOnDelete();
base.OnModelCreating(modelBuilder);
}
}
public static class MyContextExtension
{
private const string Values = "Values";
public static List<AttributeBase> AttributesWithData1(this MyContext context)
{
var attributeBases = new List<AttributeBase>();
var stringListAttributes = context.Attributes.Include(Values).OfType<StringListAttribute>().ToList();
attributeBases.AddRange(stringListAttributes);
return attributeBases;
}
}
我的测试项目(我正在使用nUnit))没什么好写的,并且包含这些方法:
public class TestHelper
{
public static StringListAttribute CreateStringListAttribute(string name, int listSize)
{
var listAttribute = new StringListAttribute();
listAttribute.Name = name;
for (int i = 0; i < listSize; i++)
{
var attr1 = new StringValue();
attr1.Value = String.Format("StringValue_{0}", i);
listAttribute.Values.Add(attr1);
}
return listAttribute;
}
}
[Test]
public void AttributeBase_GetAllAttributesWithData1()
{
//First add some data to the database
var numberOfObjects = 100;
var name = "StringListAttribute_ReadMultipleStringsListsFromDb_" + Guid.NewGuid().ToString();
var listAttributes = TestHelper.CreateStringLists(name, numberOfObjects);
using (var context = new MyContext())
{
foreach (var stringListAttribute in listAttributes)
{
context.Attributes.Add(stringListAttribute);
}
context.SaveChanges();
}
Stopwatch sw = new Stopwatch()
var attributes = new List<AttributeBase>();
using (var context = new MyContext())
{
sw.Start();
attributes = context.AttributesWithData1().ToList();
sw.Stop();
}
Debug.WriteLine(String.Format("Total time for {0} attributes is: {1}.", attributes.Count, sw.Elapsed));
Assert.IsNotNull(attributes);
}
运行测试方法“AttributeBase_GetAllAttributesWithData1”时执行的sql语句如下所示:
SELECT
[Project1].[Id] AS [Id],
[Project1].[C1] AS [C1],
[Project1].[Name] AS [Name],
[Project1].[AttributeDescription] AS [AttributeDescription],
[Project1].[Length] AS [Length],
[Project1].[AllowNull] AS [AllowNull],
[Project1].[DisplayInWeb] AS [DisplayInWeb],
[Project1].[Document_Id] AS [Document_Id],
[Project1].[C2] AS [C2],
[Project1].[StringValueId] AS [StringValueId],
[Project1].[Value] AS [Value],
[Project1].[StringListAttribute_Id] AS [StringListAttribute_Id]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[AttributeDescription] AS [AttributeDescription],
[Extent1].[Length] AS [Length],
[Extent1].[AllowNull] AS [AllowNull],
[Extent1].[DisplayInWeb] AS [DisplayInWeb],
[Extent1].[Document_Id] AS [Document_Id],
'0X0X' AS [C1],
[Extent2].[StringValueId] AS [StringValueId],
[Extent2].[Value] AS [Value],
[Extent2].[StringListAttribute_Id] AS [StringListAttribute_Id],
CASE WHEN ([Extent2].[StringValueId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
FROM [dbo].[AttributeBases] AS [Extent1]
LEFT OUTER JOIN [dbo].[StringValues] AS [Extent2] ON [Extent1].[Id] = [Extent2].[StringListAttribute_Id]
WHERE [Extent1].[Discriminator] = 'StringListAttribute'
) AS [Project1]
ORDER BY [Project1].[Id] ASC, [Project1].[C2] ASC
当我在SQL Server Management Studio中运行此sql语句时,它非常快,但实体框架需要很长时间来处理结果并返回填充了数据的poco类。
有没有其他方法来建模AttributeBase,StringListAttribute和StringValue类以及它们之间的关系以减少EF中的处理时间?