Напомним: я хочу создать высокопроизводительный DAL службы WCF (уровень доступа к данным), который возвращает строго типизированные хранимые процедуры.Сначала я использовал проект «Службы данных WCF» для достижения этой цели.Кажется, что у него есть свои ограничения, и после просмотра показателей производительности различных ORM я в конечном итоге использовал Dapper для доступа к данным внутри базовой службы WCF.
Сначала я создал модель * .edmx и создал POCO для моего sproc.
Затем я создал базовый BaseRepository и MiscDataRepository:
namespace WcfDataService.Repositories
{
public abstract class BaseRepository
{
protected static void SetIdentity<T>(IDbConnection connection, Action<T> setId)
{
dynamic identity = connection.Query("SELECT @@IDENTITY AS Id").Single();
T newId = (T)identity.Id;
setId(newId);
}
protected static IDbConnection OpenConnection()
{
IDbConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["PrimaryDBConnectionString"].ConnectionString);
connection.Open();
return connection;
}
}
}
namespace WcfDataService.Repositories
{
public class MiscDataRepository : BaseRepository
{
public IEnumerable<GetData_Result> SelectAllData()
{
using (IDbConnection connection = OpenConnection())
{
var theData = connection.Query<GetData_Result>("sprocs_GetData",
commandType: CommandType.StoredProcedure);
return theData;
}
}
}
}
Класс обслуживания:
namespace WcfDataService
{
public class Service1 : IService1
{
private MiscDataRepository miscDataRepository;
public Service1()
: this(new MiscDataRepository())
{
}
public Service1(MiscDataRepository miscDataRepository)
{
this.miscDataRepository = miscDataRepository;
}
public IEnumerable<GetData_Result> GetData()
{
return miscDataRepository.SelectAllData();
}
}
}
... и затем создал простое консольное приложение для отображения данных:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Service1Client client = new Service1Client();
IEnumerable<GetData_Result> result = client.GetData();
foreach (GetData_Result d in result)
{
Console.WriteLine(d.ID + "\t" + d.WHO_TYPE_NAME + "\t" + d.CREATED_DATE);
}
Console.Read();
}
}
}
Я также выполнил это с помощью PetaPOCO , что заняло гораздо меньше времени для настройки, чемDapper - несколько строк кода:
namespace PetaPocoWcfDataService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
public class Service1 : IService1
{
public IEnumerable<GetData_Result> GetData()
{
var databaseContext = new PetaPoco.Database("PrimaryDBContext"); // using PetaPOCO for data access
databaseContext.EnableAutoSelect = false; // use the sproc to create the select statement
return databaseContext.Query<GetData_Result>("exec sproc_GetData");
}
}
}
Мне нравится, как быстро и просто настроить PetaPOCO, но использование шаблона репозитория с Dapper будет гораздо лучше масштабироваться для корпоративного проекта.
Также было довольно просто создавать сложные объекты непосредственно из EDMX - для любой хранимой процедуры, а затем использовать их.
Например, я создал сложный тип возвращаемого типа с именем ProfileDetailsByID_Result
на основе sq_mobile_profile_get_by_id
sproc.
public ProfileDetailsByID_Result GetAllProfileDetailsByID(int profileID)
{
using (IDbConnection connection = OpenConnection("DatabaseConnectionString"))
{
try
{
var profile = connection.Query<ProfileDetailsByID_Result>("sq_mobile_profile_get_by_id",
new { profileid = profileID },
commandType: CommandType.StoredProcedure).FirstOrDefault();
return profile;
}
catch (Exception ex)
{
ErrorLogging.Instance.Fatal(ex); // use singleton for logging
return null;
}
}
}
Так что использование Dapper вместе с некоторыми объектами EDMX выглядит довольно быстроспособ добиться цели.Возможно, я ошибаюсь, но я не уверен, почему Microsoft не думала об этом все время - нет поддержки сложных типов с OData.
--- UPDATE ---
Итак, я наконец получил ответ от Microsoft, когда более месяца назад поднял вопрос:
Мы провели исследование по этому вопросу и обнаружили, что клиентская библиотека Odata неПоддерживает сложные типы.Поэтому я с сожалением сообщаю вам, что мы мало что можем сделать, чтобы решить ее.
* Необязательно: Чтобы получить решение этой проблемы, вы должны использовать подход типа Xml to Linqчтобы получить сложные типы.
Большое спасибо за ваше понимание в этом вопросе.Пожалуйста, дай мне знать, если возникнут какие-либо вопросы.Если нам понадобится дополнительная помощь, пожалуйста, сообщите нам.
С уважением,
Кажется странным.