Чтобы включить тот же edmx для доступа к нескольким базам данных и поставщикам баз данных, и наоборот, я использую следующий метод:
1) Определить ConnectionManager:
public static class ConnectionManager
{
public static string GetConnectionString(string modelName)
{
var resourceAssembly = Assembly.GetCallingAssembly();
var resources = resourceAssembly.GetManifestResourceNames();
if (!resources.Contains(modelName + ".csdl")
|| !resources.Contains(modelName + ".ssdl")
|| !resources.Contains(modelName + ".msl"))
{
throw new ApplicationException(
"Could not find connection resources required by assembly: "
+ System.Reflection.Assembly.GetCallingAssembly().FullName);
}
var provider = System.Configuration.ConfigurationManager.AppSettings.Get(
"MyModelUnitOfWorkProvider");
var providerConnectionString = System.Configuration.ConfigurationManager.AppSettings.Get(
"MyModelUnitOfWorkConnectionString");
string ssdlText;
using (var ssdlInput = resourceAssembly.GetManifestResourceStream(modelName + ".ssdl"))
{
using (var textReader = new StreamReader(ssdlInput))
{
ssdlText = textReader.ReadToEnd();
}
}
var token = "Provider=\"";
var start = ssdlText.IndexOf(token);
var end = ssdlText.IndexOf('"', start + token.Length);
var oldProvider = ssdlText.Substring(start, end + 1 - start);
ssdlText = ssdlText.Replace(oldProvider, "Provider=\"" + provider + "\"");
var tempDir = Environment.GetEnvironmentVariable("TEMP") + '\\' + resourceAssembly.GetName().Name;
Directory.CreateDirectory(tempDir);
var ssdlOutputPath = tempDir + '\\' + Guid.NewGuid() + ".ssdl";
using (var outputFile = new FileStream(ssdlOutputPath, FileMode.Create))
{
using (var outputStream = new StreamWriter(outputFile))
{
outputStream.Write(ssdlText);
}
}
var eBuilder = new EntityConnectionStringBuilder
{
Provider = provider,
Metadata = "res://*/" + modelName + ".csdl"
+ "|" + ssdlOutputPath
+ "|res://*/" + modelName + ".msl",
ProviderConnectionString = providerConnectionString
};
return eBuilder.ToString();
}
}
2) Изменить T4, который создает ваш ObjectContext, чтобы он использовал ConnectionManager:
public partial class MyModelUnitOfWork : ObjectContext
{
public const string ContainerName = "MyModelUnitOfWork";
public static readonly string ConnectionString
= ConnectionManager.GetConnectionString("MyModel");
3) Добавьте следующие строки в App.Config:
<?xml version="1.0" encoding="utf-8"?> <configuration> <connectionStrings> <add name="MyModelUnitOfWork" connectionString=... /> </connectionStrings> <appSettings> <add key="MyModelUnitOfWorkConnectionString" value="data source=MyPc\SqlExpress;initial catalog=MyDB;integrated security=True;multipleactiveresultsets=True" /> <add key="MyModelUnitOfWorkProvider" value="System.Data.SqlClient" /> </appSettings> </configuration>
ConnectionManager заменит ConnectionString и Provider к тому, что когда-либо было в App.Config.
Вы можете использовать тот же ConnectionManager для всех объектов ObjectContext (чтобы все они читали одни и те же настройки из App.Config) или редактировали T4, чтобы он создавал один ConnectionManager для каждого (в собственном пространстве имен), так что каждый считывает отдельные настройки.
Этот мог бы быть хорош Различный Патч Соответствия .
В зависимости от Ваших строгих требований StringUtils
класс компонент Apache Commons Lang мог бы быть полезным, например:
Вот (слегка протестированная) версия кода, который делает то, что Вы спросили. Можно легко пересечь результат параллельно с исходными данными для определения местоположения вставок и удалений.
public class StringDiff {
private static int length(String s) { return s == null ? 0 : s.length(); }
private static char[] chars(String s) { return s == null ? new char[0] : s.toCharArray(); }
private final String left;
private final String right;
private final char[] lccs;
private final String lcs;
public StringDiff(String left, String right) {
this.left = left;
this.right = right;
lccs = init();
lcs = new String(lccs);
}
public String getLcs() { return lcs; }
public char[] getLccs() { return lccs.clone(); }
private char[] init() {
int lLength = length(left);
int rLength = length(right);
char[] lChars = chars(left);
char[] rChars = chars(right);
int [][] t = new int [lLength + 1][rLength + 1];
for (int i = lLength - 1; i >= 0; --i) {
for (int j = rLength - 1; j >= 0; --j) {
if (lChars[i] == rChars[j]) {
t[i][j] = t[i + 1][j + 1] + 1;
} else {
t[i][j] = Math.max(t[i + 1][j], t[i][j + 1]);
}
}
}
char[] result = new char[t[0][0]];
int l = 0, r = 0, p = 0;
while (l < lLength && r < rLength) {
if (lChars[l] == rChars[r]) {
result[p++] = lChars[l++];
r++;
} else {
if (t[l + 1][r] > t[l][r + 1]) {
++l;
} else {
++r;
}
}
}
return result;
}
}
Согласно ему, фактическая самая длинная подпоследовательность Ваших исходных исходных данных:
The quick brown fox jumped over the lazy dog.
The quick yellow fox jumped over the well-bred dog.
:
The quick ow fox jumped over the l dog.
(потому что "коричневый" и "желтый" имеют "ой" вместе, и т.д.)
Это относительно просто для изменения вышеупомянутого, чтобы разделить на пробеле (вместо в массивы символов) и заменить String#equals == для получения версии, которая находит самую длинную общую подпоследовательность слов вместо символов. Поскольку Ваш пример выше того изменения привел бы к очевидному результату:
found 7 words
'The'
'quick'
'fox'
'jumped'
'over'
'the'
'dog.'
(Ваш вопрос подразумеваемые символьные сравнения, когда Вы соответствовали пробелам между словами.)
Если Вы - пример, действительно, что Вы хотите сделать - т.е. подпоследовательности только соответствуют, если они запускают в том же индексе (который отличается от того, как diffs обычно работают) - это - все, что необходимо сделать:
import java.util.*;
class StringDiff {
public static List<int[]> from(String s1, String s2) {
int start = -1;
int pos = 0;
LinkedList<int[]> list = new LinkedList<int[]>();
for(; pos < s1.length() && pos < s2.length(); ++pos) {
if(s1.charAt(pos) == s2.charAt(pos)) {
if(start < 0) start = pos;
}
else {
if(start >= 0) list.add(new int[] { start, pos });
start = -1;
}
}
if(start >= 0) list.add(new int[] { start, pos });
return list;
}
public static void main(String[] args) {
for(int[] idx : from(args[0], args[1]))
System.out.println(args[0].substring(idx[0], idx[1]));
}
}
фактическая различная реализация будет намного более сложной.